How can I search any volume in macOS? - objective-c

- (void)readFolder:(NSString *)str :(NSMutableDictionary *)dict {
NSArray *appFolderContents = [[NSArray alloc] init];
appFolderContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:str error:nil];
for (NSString *app in appFolderContents) {
if ([app containsString:#".app"])
{
NSString *appName = [[app lastPathComponent] stringByDeletingPathExtension];
NSString *appPath = [NSString stringWithFormat:#"%#/%#", str, app];
NSString *appBundle = [[NSBundle bundleWithPath:appPath] bundleIdentifier];
// NSLog(#"%# -- %#", appPath, appBundle);
NSArray *jumboTron = [NSArray arrayWithObjects:appName, appPath, appBundle, nil];
[dict setObject:jumboTron forKey:appName];
}
}
}
//This searches for apps
- (void)getAPPList {
NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init];
[self readFolder:#"/Applications" :myDict];
[self readFolder:#"/Applications/Utilities" :myDict];
[self readFolder:#"/System/Library/CoreServices" :myDict];
[self readFolder:#"/Volumes/Macintosh HD/Applications" :myDict ];
// Volumes not named 'Macintosh HD' doesn't work, I'm trying to make it work
[self readFolder:#"/Volumes/*/Applications" :myDict ];
//Some apps are stored in the user's Application folder instead of the main one
[self readFolder:[NSString stringWithFormat:#"%#/Applications", NSHomeDirectory()] :myDict];
//Sometimes people keep apps in Downloads
[self readFolder:[NSString stringWithFormat:#"%#/Downloads", NSHomeDirectory()] :myDict];
//Some apps are stored in the user's Library/Application Support sometimes
[self readFolder:[NSString stringWithFormat:#"%#/Library/Application Support", NSHomeDirectory()] :myDict];
I'm trying to make line 26 ([self readFolder:#"/Volumes/*/Applications" :myDict ]) search all volumes, instead of only searching a volume with a matching/specific name. How can I do this?
I'm using Xcode 9.2

something like this should do the trick (untested)
NSArray *keys = [NSArray arrayWithObjects:NSURLVolumeURLKey, NSURLIsVolumeKey, nil];
NSArray *volumeUrls = [[NSFileManager defaultManager] mountedVolumeURLsIncludingResourceValuesForKeys:keys options:NSVolumeEnumerationSkipHiddenVolumes];
for (NSURL *volumeUrl in volumeUrls)
{
BOOL mayBeBootVolume = NO;
NSString* pathToVolume = [volumeUrl path];
[self readFolder: [pathToVolume stringByAppendingString: #"/Applications"];
}

Related

OBJ. C. (XCODE 5 - IOS 7) Auto save variables in a property list

I want to save automatically my variables (floats) in a property list that I've already create. I can do that with a button, that work good but I want to do that automatically WITH IOS 7 (some methods are deprecated in IOS 6 or 7).
replyToApplicationShouldTerminate
doesn't work...
I save in the property list with a button like that:
-(IBAction)apply:(id)sender
{
{
[nameC1 resignFirstResponder];
[nameC2 resignFirstResponder];
[nameC3 resignFirstResponder];
[nameC4 resignFirstResponder];
[nameC5 resignFirstResponder];
nom1 = [nameC1 text];
nom2 = [nameC2 text];
nom3 = [nameC3 text];
nom4 = [nameC4 text];
nom5 = [nameC5 text];
v1 = [NSString stringWithFormat:#"%d", compteur1];
v2 = [NSString stringWithFormat:#"%d", compteur2];
v3 = [NSString stringWithFormat:#"%d", compteur3];
v4 = [NSString stringWithFormat:#"%d", compteur4];
v5 = [NSString stringWithFormat:#"%d", compteur5];
//Write in Data.plist
NSString *error;
NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [rootPath stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *plistDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: nom1, nom2, nom3, nom4, nom5, v1, v2, v3, v4, v5, nil] forKeys:[NSArray arrayWithObjects: #"nomCompteur1", #"nomCompteur2", #"nomCompteur3", #"nomCompteur4", #"nomCompteur5", #"valeurCompteur1", #"valeurCompteur2", #"valeurCompteur3", #"valeurCompteur4", #"valeurCompteur5",nil]];
NSData *plistData = [NSPropertyListSerialization dataFromPropertyList:plistDict
format:NSPropertyListXMLFormat_v1_0
errorDescription:&error];
if(plistData) {
[plistData writeToFile:plistPath atomically:YES];
}
else {
NSLog(#"error");
//[error release];
}
}
}
In after the nib is loaded, register a notification for value changes in each of your text fields:
- (void)awakeFromNib
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(UITextFieldTextDidChange:)
name:UITextFieldTextDidChangeNotification
object:nameC1];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(UITextFieldTextDidChange:)
name:UITextFieldTextDidChangeNotification
object:nameC2];
...
}
And when the text changes, save the data:
- (void)UITextFieldTextDidChange:(NSNotification*)notification
{
[self save];
}
- (void)save
{
...
}
You might want to get a bit more fancy, and use dispatch_after() to wait ~0.5 seconds before doing the save. That way the user won't notice if the save is a bit slow. But I suspect the save will be very fast in this case.

To see more than pointers in an array (objective C)

If i enumerate an array i get
<myArray: 0x71b26b0>
<myArray: 0x71b2830>
<myArray: 0x71b2900>
I could take it that myData is behind the pointers listed, but if I wanted to explicitly see (log) the contents at each address, how to do that?
I have tried the &myData to no avail
--
for the benefit of uchuugaka:
-(void)loadObservedItems{
NSString *path = [self observationFilePath];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
myArray = [unarchiver decodeObjectForKey:#"ObserveKey"];
[unarchiver finishDecoding];
} else {
myArray = [[NSMutableArray alloc] initWithCapacity:10];
}
NSLog(#" %#",myArray);
}
Add to MyClass.m:
-(NSString*)description {
NSMutableDictionary* descDict = [NSMutableDictionary dictionary];
[descDict addObject:someField forKey:#"someField"]
[descDict addObject:anotherField forKey:#"anotherField"];
[descDict addObject:yetAnotherField forKey:#"yetAnotherField"];
return [descDict description];
}
Then just use NSLog(#"myObject is %#", myObject);. Just like the big guys.
Slightly more sophisticated is to (within the method) pre-pend your class name and the object address to the result string, but that's usually unnecessary for simple debugging.
But I think you can do that like this:
return [NSString stringWithFormat:#"%# : %#", [super description], [descDict description]];

How to load multiple languages to IVONA SDK - text to speech

I want to load multiple languages to use IVONA SDK with SSML for iPhone.
There is no documentation for use in Xcode/objective-C, only the SDK itself is given and several C/java examples.
How can you load multiple languages for text to speach with IVONA SDK for iOS?
EDIT 1: see my code below
load the voices at first:
- (NSInteger) loadVoice: (NSString*) vox {
if(voice != nil) {
XLog(#"(voice != nil)");
[voice unload];
voice = nil;
}
NSString *pathIvona = [[NSString alloc] initWithFormat:#"%#", vox];
self.paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [self.paths objectAtIndex:0];
self.path = [self.documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"%#", pathIvona]];
voice = [[IvonaVoice alloc] init:instance withLibrary:self.path withVox:self.path];
[pathIvona release];
if (voice == nil) {
XLog(#"Cannot load voice");
[self setTtsError: #"Cannot load voice"];
return 0;
}
[voice setParam:#"vol" withInteger: 99];
return 1;
}
trying to load multiple languages to one streamer with (the streamer is still nil, it doesnt change):
NSArray *allVoices = [self getAvaliableVoxes];
/**
* Here the streamer is still nil,
* i cant find the mistake here.
*
*/
IvonaStreamer *streamer = [[IvonaStreamer alloc] initWithVoices:allVoices
withText:[NSString stringWithContentsOfFile:self.path
encoding:NSUTF8StringEncoding error:&error] atSpeed:[NSNumber numberWithFloat:-1]];
Method getAvailableVoices:
- (NSArray*)getAvaliableVoxes {
XLog(#"-----------------------------------entered");
self.paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.documentsDirectory = [self.paths objectAtIndex:0];
NSFileManager *manager = [NSFileManager defaultManager];
NSArray *fileList = [manager contentsOfDirectoryAtPath:[self.paths objectAtIndex:0] error:nil];
for (NSString *s in fileList){
//XLog(#"s: %#", s);
}
NSMutableArray *pathsIvona = [[NSMutableArray alloc] init];
NSEnumerator *e = [fileList objectEnumerator];
NSString *vox;
while (vox = [e nextObject]) {
if([[vox lastPathComponent] hasPrefix:#"vox_"]) {
XLog(#"vox: %#", vox);
[pathsIvona addObject: [vox lastPathComponent]];
XLog(#"pathsIvona: %#", pathsIvona);
}
}
XLog(#"pathsIvona: %#", pathsIvona);
return [pathsIvona autorelease];
}
How can you load multiple languages in one streamer on iOS with IVONA SDK?
perhaps the objects added to the array allVoices do not conform to the expected array of initWithVoices: ...

Objective-C: How to add query parameter to NSURL?

Let's say I have an NSURL? Whether or not it already has an empty query string, how do I add one or more parameters to the query of the NSURL? I.e., does anyone know of an implementation of this function?
- (NSURL *)URLByAppendingQueryString:(NSString *)queryString
So that it satisfies this NSURL+AdditionsSpec.h file:
#import "NSURL+Additions.h"
#import "Kiwi.h"
SPEC_BEGIN(NSURL_AdditionsSpec)
describe(#"NSURL+Additions", ^{
__block NSURL *aURL;
beforeEach(^{
aURL = [[NSURL alloc] initWithString:#"http://www.example.com"];
aURLWithQuery = [[NSURL alloc] initWithString:#"http://www.example.com?key=value"];
});
afterEach(^{
[aURL release];
[aURLWithQuery release];
});
describe(#"-URLByAppendingQueryString:", ^{
it(#"adds to plain URL", ^{
[[[[aURL URLByAppendingQueryString:#"key=value&key2=value2"] query] should]
equal:#"key=value&key2=value2"];
});
it(#"appends to the existing query sting", ^{
[[[[aURLWithQuery URLByAppendingQueryString:#"key2=value2&key3=value3"] query] should]
equal:#"key=value&key2=value2&key3=value3"];
});
});
});
SPEC_END
Since iOS 7 you can use NSURLComponents that is very simple to use. Take a look on these examples:
Example 1
NSString *urlString = #"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];
NSLog(#"%# - %# - %# - %#", components.scheme, components.host, components.query, components.fragment);
Example 2
NSString *urlString = #"https://mail.google.com/mail/u/0/?shva=1#inbox";
NSURLComponents *components = [[NSURLComponents alloc] initWithString:urlString];
if (components) {
//good URL
} else {
//bad URL
}
Example 3
NSURLComponents *components = [NSURLComponents new];
[components setScheme:#"https"];
[components setHost:#"mail.google.com"];
[components setQuery:#"shva=1"];
[components setFragment:#"inbox"];
[components setPath:#"/mail/u/0/"];
[self.webview loadRequest:[[NSURLRequest alloc] initWithURL:[components URL]]];
But you can do many other things with NSURLComponents take a look on NSURLComponents class reference on Apple documentation or on this link: http://nshipster.com/nsurl/
Here's an implementation that passes your specs:
#implementation NSURL (Additions)
- (NSURL *)URLByAppendingQueryString:(NSString *)queryString {
if (![queryString length]) {
return self;
}
NSString *URLString = [[NSString alloc] initWithFormat:#"%#%#%#", [self absoluteString],
[self query] ? #"&" : #"?", queryString];
NSURL *theURL = [NSURL URLWithString:URLString];
[URLString release];
return theURL;
}
#end
And here is an implementation for NSString:
#implementation NSString (Additions)
- (NSURL *)URLByAppendingQueryString:(NSString *)queryString {
if (![queryString length]) {
return [NSURL URLWithString:self];
}
NSString *URLString = [[NSString alloc] initWithFormat:#"%#%#%#", self,
[self rangeOfString:#"?"].length > 0 ? #"&" : #"?", queryString];
NSURL *theURL = [NSURL URLWithString:URLString];
[URLString release];
return theURL;
}
// Or:
- (NSString *)URLStringByAppendingQueryString:(NSString *)queryString {
if (![queryString length]) {
return self;
}
return [NSString stringWithFormat:#"%#%#%#", self,
[self rangeOfString:#"?"].length > 0 ? #"&" : #"?", queryString];
}
#end
The iOS8+ modern way
adding (or replacing 'ref' value if exists) ref=impm to url which is on min60.com
if ([[url host] hasSuffix:#"min60.com"]) {
NSURLComponents *components = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO];
NSURLQueryItem * newQueryItem = [[NSURLQueryItem alloc] initWithName:#"ref" value:#"impm"];
NSMutableArray * newQueryItems = [NSMutableArray arrayWithCapacity:[components.queryItems count] + 1];
for (NSURLQueryItem * qi in components.queryItems) {
if (![qi.name isEqual:newQueryItem.name]) {
[newQueryItems addObject:qi];
}
}
[newQueryItems addObject:newQueryItem];
[components setQueryItems:newQueryItems];
url = [components URL];
}
Just a friendly post for those who don't want to write boilerplate code while building NSURL with NSURLComponents.
Since iOS8 we have NSURLQueryItem that helps building URL request freaking fast.
I wrote a little handy category to ease the work, that you can grab here: URLQueryBuilder
Here is example of how easy it is to work with it:
NSString *baseURL = #"https://google.com/search";
NSDictionary *items = #{
#"q" : #"arsenkin.com",
#"hl" : #"en_US",
#"lr" : #"lang_en"
};
NSURL *URL = [NSURL ars_queryWithString:baseURL queryElements:items];
// https://google.com/search?q=arsenkin.com&hl=en_US&lr=lang_en
I have an extension to NSURLComponents that add query item, in swift:
extension NSURLComponents {
func appendQueryItem(name name: String, value: String) {
var queryItems: [NSURLQueryItem] = self.queryItems ?? [NSURLQueryItem]()
queryItems.append(NSURLQueryItem(name: name, value: value))
self.queryItems = queryItems
}
}
To use,
let components = NSURLComponents(string: urlString)!
components.appendQueryItem(name: "key", value: "value")
If you're using RestKit it provides additions to NSString. One of which is:
- (NSString *)stringByAppendingQueryParameters:(NSDictionary *)queryParameters
So you could do:
NSDictionary *shopParams = [NSDictionary dictionaryWithKeysAndObjects:
#"limit",#"20",
#"location",#"latitude,longitude",
nil];
NSString *pathWithQuery = [#"/api/v1/shops.json" stringByAppendingQueryParameters:shopParams]
As others have mentioned, you can use NSURLComponents to construct URLs.
#implementation NSURL (Additions)
- (NSURL *)URLByAppendingQueryParameters:(NSDictionary *)queryParameters
{
NSURLComponents *components = [[NSURLComponents alloc] initWithURL:self resolvingAgainstBaseURL:NO];
NSMutableArray *queryItems = [NSMutableArray array:components.queryItems];
for (NSString *key in [queryParameters allKeys]) {
NSURLQueryItem *queryItem = [[NSURLQueryItem alloc] initWithName:key value:queryParameters[key]];
[queryItems addObject:queryItem];
}
components.queryItems = queryItems;
return [components URL];
}
#end
NSURL is not mutable so you cannot implement this functionality directly based on NSURL. Instead you will have to obtain the string representation of the URL, append your parameters to that and then create a new NSURL.
This does not sound like a good solution. Unless there is a good reason, it is better to work with strings until the last moment and only create an NSURL when you have your fully formed request.

Add data to plist

I want to create a plist in code and add more "records" from user input to it. I have created a plist, and I can write the user input, but I can't add data to my plist. Every time, it saves the last input and keeps only one "record". This is the code:
-(void) createPlistFile {
manager = [NSFileManager defaultManager];
filepath = #"/Users/agnostos_el/Downloads/PhoneBook/PhoneBook/Epafes.txt";
if ( [manager fileExistsAtPath:filepath] == NO )
{
NSLog(#"Το Αρχειο Δεν Υπαρχει Το δημειουργω");
[[NSFileManager defaultManager]createFileAtPath:filepath contents:nil attributes:nil];
}
}
-(void) openPlistFile {
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if( [path count] > 0 ){
pListFile = [[path objectAtIndex:0] stringByAppendingPathComponent:filepath];
NSDictionary *pListDict = [[NSDictionary alloc]initWithContentsOfFile:filepath];
if ( [pListDict count] <= 0 )
{
}
[self createPlistFile];
}
}
- (void) times
{
filepath = #"/Users/agnostos_el/Downloads/PhoneBook/PhoneBook/Epafes.txt";
stoixeia = [NSArray arrayWithObjects:onoma.stringValue, poli.stringValue, odos.stringValue, per.stringValue, tk.stringValue, xora.stringValue,kin.stringValue, kin1.stringValue, kin2.stringValue, kat.stringValue, erg.stringValue, fax.stringValue, email.stringValue, email1.stringValue, email2.stringValue, pros.stringValue, sim.stringValue, nil];
eponimos = epitheto.stringValue;
NSMutableDictionary *atomo = [NSMutableDictionary dictionary];
innerDict = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects: eponimos, stoixeia, nil]
forKeys:[NSArray arrayWithObjects:#"eponimo", #"stoixeia", nil]];
[atomo setObject:innerDict forKey:eponimos];
id plist = [NSPropertyListSerialization dataFromPropertyList:(id)atomo
format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];
record = [[NSData alloc]initWithData:plist];
[record writeToFile:filepath atomically:YES];
}
- (void) eggrafi
{
[self openPlistFile];
[self times];
}
Any suggestions? Thanks.
You are not passing the file contents to createFileAtPath:contents:attributes::
[[NSFileManager defaultManager]createFileAtPath:filepath contents:nil attributes:nil];