How can I use OpenEars in a tweak? - ios

I'm trying to include OpenEars in a theos project I'm making, a tweak for jailbroken iDevices, as I need speech recognition for my tweak. I was able to link the OpenEars framework by putting it in the same folder as my private frameworks, and I'm currently trying to get the tutorial code to work. Here's my current code:
#import <OpenEars/LanguageModelGenerator.h>
#import <OpenEars/PocketsphinxController.h>
#import <OpenEars/AcousticModel.h>
%hook SBLockScreenView
-(void)setCustomSlideToUnlockText:(id)arg1 {
LanguageModelGenerator *lmGenerator = [[LanguageModelGenerator alloc] init];
NSArray *words = [NSArray arrayWithObjects:#"WORD", #"STATEMENT", #"OTHER WORD", #"A PHRASE", nil];
NSString *name = #"NameIWantForMyLanguageModelFiles";
NSError *err = [lmGenerator generateLanguageModelFromArray:words withFilesNamed:name forAcousticModelAtPath:[AcousticModel pathToModel:#"AcousticModelEnglish"]];
//NSError* err = [lmGenerator generateLanguageModelFromArray:words withFilesNamed:name forAcousticModelAtPath:imagePath];
//NSError* err = [[NSError alloc] init];
NSDictionary *languageGeneratorResults = nil;
NSString *lmPath = nil;
NSString *dicPath = nil;
if([err code] == noErr) {
languageGeneratorResults = [err userInfo];
lmPath = [languageGeneratorResults objectForKey:#"LMPath"];
dicPath = [languageGeneratorResults objectForKey:#"DictionaryPath"];
}
else {
NSLog(#"Error: %#",[err localizedDescription]);
}
%orig;
}
%end
This compiles fine, but when it runs, I get these error messages and my device crashes: "While trying to reference the requested acoustic model bundle which is expected to be at the path (null), no bundle was found. This means that when the listening loop begins, it will crash due to the missing required resources. The problem finding the acoustic model bundle could be because the name of the bundle was not given to this method in a way it can use; for instance, if you are trying to use the English acoustic model and you have added that bundle to your app project, you would invoke this method by passing [AcousticModel pathToAcousticModel:#"AcousticModelEnglish"] (or [AcousticModel pathToAcousticModel:#"AcousticModelSpanish"] for the Spanish bundle), without appending ".bundle" to the end, and making sure that the bundle name is spelled exactly as it appears in the actual bundle name (the bundle can be seen in this distribution's folder "Framework".
If this doesn't fix the problem, it is very likely to be due to the fact that the acoustic model bundle wasn't imported successfully into the root level of your app project and its mainBundle. This usually happens either because the acoustic model bundle was never dragged into your app project when the "Framework" folder was originally supposed to be dragged in, or because it was dragged in but instead of using the setting "Create groups for any added folders" in Xcode's "Add Files" dialog, the option "Create folder references for any added folders" was unintentionally chosen. To fix this, just remove the acoustic model bundle or the "Framework" folder from your app and add it again to your app project with the correct setting of "Create groups for any added folders" in Xcode's "Add Files" dialog."
I also get these messages in my syslog:
May 27 00:54:49 Phillips-iPhone SpringBoard[17785] <Warning>: acousticModelPath is (null)
May 27 00:54:49 Phillips-iPhone SpringBoard[17785] <Warning>: Error: the default phonetic dictionary (null)/LanguageModelGeneratorLookupList.text can't be found in the app bundle but the app is attempting to access it, most likely there will be a crash now.
May 27 00:54:49 Phillips-iPhone SpringBoard[17785] <Warning>: Error while trying to load the pronunciation dictionary: Error Domain=NSCocoaErrorDomain Code=260 "The operation couldn’t be completed. (Cocoa error 260.)" UserInfo=0x1883cbb0 {NSFilePath=(null)/LanguageModelGeneratorLookupList.text, NSUnderlyingError=0x1883cb40 "The operation couldn’t be completed. No such file or directory"}
May 27 00:54:49 Phillips-iPhone SpringBoard[17785] <Error>: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid domain=nil in -[NSError initWithDomain:code:userInfo:]'
Any help in getting this working is greatly appreciated. Thanks!

I recently made an OpenEars based iOS tweak and I went through the same problem. Because your tweak is not a normal app, the location that pathToAcousticModel gives will not be correct. The easiest solution is to place the acoustic model bundle in a known location and hard code it.
For example, if you are using theos you can place AcousticModelEnglish.bundle in the folder "layout/Library/OpenEars/". Then replace
[AcousticModel pathToAcousticModel:#"AcousticModelEnglish"]
with
#"/Library/OpenEars/AcousticModelEnglish.bundle"

The easiest solution that I found was dragging the "Framework" folder from the OpenEars library that contains the bundle files to the "Frameworks" folder inside the Xcode project. After dragging, mark the option "copy items if needed".
It sounds strange in the first look but this solution works and you won't change the code.
You will get a file structure like that:
You can also remove the oldest references of these libraries under the "Framework" folder to keep your project clean.
Cheers,
David

Related

Can't read or create UIManagedDocuments anymore

I have a big issue in my app, which prevents creating new documents and reading them, whereas it worked well until now.
I didn't change anything, and it started bugging from a build to another.
This is the code I'm using:
CLProject *project = [[CLProject alloc] initWithFileURL:projectURL];
NSLog (#"Will save project at URL: %#", projectURL);
[project saveToURL:projectURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
NSLog (#"Project saved: %d", success);
[...]
}];
CLProject is a subclass of UIManagedDocument.
The first NSLog is called, but not the second one. Instead I get an error :
2018-02-14 19:21:03.597495+0100 CamList[2247:750786] Will save project
at URL:
file:///var/mobile/Containers/Data/Application/151E38F5-2214-4876-A188-2AB8B5E8CF6A/Documents/Projects/715A0087-F2EF-439B-A2DD-8E878EF8A973.camlist
2018-02-14 19:21:03.783397+0100 CamList[2247:750886] [default] [ERROR]
Could not get attribute values for item
/var/mobile/Containers/Data/Application/151E38F5-2214-4876-A188-2AB8B5E8CF6A/Documents/Projects/715A0087-F2EF-439B-A2DD-8E878EF8A973.camlist
(n). Error: Error Domain=NSFileProviderInternalErrorDomain Code=1 "The
reader is not permitted to access the URL."
UserInfo={NSLocalizedDescription=The reader is not permitted to access
the URL.}
But it doesn't crash, the app keeps running (but nothing happens because the completion block never gets called).
What I don't understand is that everything was working fine and I haven't changed anything...
Can you help me??
Thanks
Well, it seems to work fine again this morning... Nothing to understand. My iPhone had to be tired...

Error initialize AZSCloudStorageAccount Swift 3

I tried link to my account with this code
let storageAccount : AZSCloudStorageAccount;
try! storageAccount = AZSCloudStorageAccount(fromConnectionString: config.getAzureConnection())
let blobClient = storageAccount.getBlobClient()
var container : AZSCloudBlobContainer = (blobClient?.containerReference(fromName: config.getContainer()))!
the "config.getAzureConnection()" contains the right path because i used the same for android app.
In this line try! storageAccount = AZSCloudStorageAccount(fromConnectionString: config.getAzureConnection()) the app crash without error, only (lldb) .
Can someone help me.
Does your error look like this?
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=com.Microsoft.AzureStorage.ErrorDomain Code=1 "(null)": file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.53/src/swift/stdlib/public/core/ErrorType.swift, line 182
(lldb)
Code=1 is AZSEInvalidArgument, which means that your connection string is invalid. I am a bit confused why you said "the right path", since fromConnectionString takes the string directly, not the path to a file. To see an example of what a correct connection string looks like, please refer to the Getting Started Guide. Basically it looks like this:
"DefaultEndpointsProtocol=https;AccountName=your_account_name_here;AccountKey=your_account_key_here"
We will document the error codes properly very soon. Sorry for the confusion!
the app crash without error, only (lldb) .
I am sorry for that SWIFT blob client haven't provide error-handling code whatsoever currently. I will provide some clues to track your issue based on your code.
Before building the storage code, make one change in the project. Go to 'Azure Storage Client Library' -> Build Settings, search for the "Defines Module" setting, and change it to 'YES'.
Please check whether the issue is caused by bad network connection.
You could get error code of this issue by putting your code in a do-catch code block.
do {
//put your code here
} catch let error as NSError {
print("Error code = %ld, error domain = %#, error userinfo = %#", error.code, error.domain, error.userInfo);
}
The SWIFT blob sample has been tested and work well targeting iOS 9.0 and using XCode 7. If you have a different setup, the sample may not run properly. I suggest you use Blob Storage REST API as a workaround.

Core Data - can't achieve a simple LightWeight Migration

I am unable to achieve a simple lightweight migration by simply adding 1 Entity to the datamodel.
I have read and followed all the guides/documentation/posts/answers, I can't seem to find my mistake/error.
I do have created a new datamodel from the already existing one.
I do have set the new datamodel as current datamodel.
I do have only added 1 Entity to the new datamodel (+ link to the parent Entity).
I do have passed the dictionary options NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption in the method addPersistentStoreWithType.
I even tried to log everything, thank to the method given from this post: core data migration
/*! The method checks the Core Data file version is compatible with the App's model version
and then pushes the main menu view onto the navigation stack. If not compatible it displays a
message to the user.
#param file The file URL for the Core Data Store. With UIManagedDocument you have to get the
actual store file URL, you can't just use the UIManagedDocument file URL.
*/
-(void) checkCoreDataFileVersion:(NSURL*)file
{
if ([self checkVersion:file]) {
// file version is compatible so continue (add code to push the menu view)
} else {
// file version is NOT compatible
_fileOpenErrorAlert = [[UIAlertView alloc] initWithTitle:#"Unable to open Document" message:#"Please check that you have the correct application version installed" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[_fileOpenErrorAlert show];
}
return;
}
/*! Checks the Core Data files models version against the apps model version to see if they
are compatible. This will return YES if a lightweight migration can be performed and NO if NOT.
#param fileURL The file URL for the Core Data Store. With UIManagedDocument you have to get the
actual store file URL, you can't just use the UIManagedDocument file URL.
#return Returns YES if they are compatible and NO if not.
*/
- (bool)checkVersion:(NSURL*)fileURL {
NSManagedObjectModel *model = [self managedObjectModel];
NSLog(#" app model entity version hashes are %#", [model entityVersionHashesByName]);
NSError *error;
NSDictionary *metaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:fileURL error:&error];
if (!metaData) {
NSLog(#"problem getting metaData");
NSLog(#" - error is %#, %#", error, error.userInfo);
return NO;
}
bool result = [model isConfiguration:nil compatibleWithStoreMetadata:metaData];
if (!result) {
NSLog(#" file is not compatible!");
NSLog(#" metadata is %#", metaData);
}
return result;
}
When I make a diff of the metadata from all the Entities, I only match difference for 1 Entity (the newly created). So why it can't make a migration ? I just added 1 Entity.
EDIT :
I don't have Crashes, the App is working fine.
There is something I don't understand. When I download our lastest App from the AppStore, launch it and when I build from xCode my lastest developement App (with the new datamodel) over the one from the AppStore, the migration doesn't occur.
BUT when I use GIT, when I put the HEAD to the lastest release TAG, build, launch the App. Then put back the HEAD to my lastest development feature (with the new datamodel etc..), build and run, the migration is done and everything is working.
So which scenario should I trust ?
Yes, You should trust the 2nd senario to test coredata migration by applying it to the last released code.
The first senario is no more valid since Apple for some security reasons nomore give the ability to update an itune-downloaded app using xcode directly.
There was a way to test the upgrade on itune-version but not directly from xcode.
Technical Note TN2285
Testing iOS App Updates
Install an ad hoc distribution of an archived build of the update
using iTunes on a device that already has the old version of the app
installed.
Installing Your App on Test Devices Using iTunes

Error while deleting the file

While deleting existing the file with this command:
[[NSFileManager defaultManager] removeItemAtPath:self.sourceFileName error:&error];
I got the following error
Error: ImageIO: CGImageReadCreateDataWithMappedFile 'open' failed '/Users/asdasd/Library/Application Support/iPhone Simulator/7.1/Applications/DD251D7D-F0AF-40E1-A033-F221623D589D/Library/ScanSession/Source/page3.jpeg
error = 2 (No such file or directory)'
This happens while I copied pic from album into app folder. The most interesting thing is that file exists, but not fully copied. Is there a way to check wether file is file operation completed?
check weather your file & Directory available
for (NSString *filename in files) {
NSString *path = [yourPath stringByAppendingPathComponent:yourFileName];
BOOL isDir;
if([[NSFileManager defaultManager] fileExistsAtPath:yourPath isDirectory:&isAvilDir] && isAvilDir){
NSLog(#"%# Check is a directory", your path file);
}
else {
NSLog (#"%# Check is a file",your path file);
}
}
I have a similar problem right now, and it seems as though when you delete a file that certain other methods you may have called immediately prior may actually not have completed yet. I'm considering delaying the actual deletion of files to allow for background processes to complete.
Solved it 2 yars ago. Forgot to post & close the question. It was caused by another thread, where the file was deleted first. I think its one of the standart mutlithreading issues while working with CoreData

iCloud sync fails with "CoreData: Ubiquity: Invalid option: the value for NSPersistentStoreUbiquitousContentNameKey should not contain periods"

CoreData: Ubiquity: Invalid option: the value for NSPersistentStoreUbiquitousContentNameKey should not contain periods: com.YashwantChauhan.Outis
-PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:: CoreData: Ubiquity: mobile~20BF44C9-C39F-48DC-A8A1-B45FC82C7E20:com.YashwantChauhan.Outis
I have a problem with syncing with iCloud. These two errors above are thrown at me. I don't know what's the problem, I setup the Entitlements file, and set the Ubiquity Container to com.YashwantChauhan.Outis.
I start the CoreData stack using MagicalRecord's method:
[MagicalRecord setupCoreDataStackWithiCloudContainer:#"N6TU2CB323.com.YashwantChauhan.Outis" localStoreNamed:#"Model.sqlite"];
But that shouldn't even matter since MagicalRecord just simplifies CoreData methods.
Help much appreciated.
Ok update:
-[NSFileManager URLForUbiquityContainerIdentifier:]: An error occurred while getting ubiquity container URL: Error
Domain=LibrarianErrorDomain Code=11 "The operation couldn’t be
completed. (LibrarianErrorDomain error 11 - The requested container
identifier is not permitted by the client's
com.apple.developer.ubiquity-container-identifiers entitlement.)"
UserInfo=0x15e0d8a0 {NSDescription=The requested container identifier
is not permitted by the client's
com.apple.developer.ubiquity-container-identifiers entitlement.}
This is the latest error message I got, I realize this differs from the question's initial error but it so turns out that the old message was some kind of strange bug of sorts. I tried #Rauru Ferro's solution by removing the periods from my Ubiquity Container identifier. I knew that this wouldn't work because the requirements for the identifier is to contain periods, but then when I put the periods back in, it spat the error message above. Which makes more a lot more sense than not using periods. We all know that we do.
I also found this handy code snippet that can actually checks my Ubiquity Container identifier by fetching it. Useful snippet to quickly check if you have any problems with it.
NSString *containerId = #"com.YashwantChauhan.Outis";
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *iCloudURL = [fileManager URLForUbiquityContainerIdentifier:containerId];
NSLog(#"%#", [iCloudURL absoluteString]);
Another update: By the looks of it, this stupid NSPersistentStoreUbiquitousContentNameKey should not contain periods is a whole mess. If NSPersistentStoreUbiquitousContentNameKey is created like some kind of folder (Tutorial), then the requirement is that there is no . infront of the name, like .com.YashwantChauhan.Outis but that is not the case. I am starting to go mad here! There is no problem with the Entitlements file and there is nothing with fetching the iCloud container ID in MagicalRecord. I am starting to think this is an internal problem with setting up iCloud in Xcode 5, but of course I don't know. With this said, I might just be loosing my mind over something trivial or something that will actually cause a headache for other people.
Can anybody post their Entitlements file so I can verify how an actual working version looks like. Redacted of course. Thank you!
refer
https://forums.pragprog.com/forums/252/topics/12315
Quoting the response:
This was changed recently (Mavericks). Fortunately for you, since you are just now adding iCloud, the impact is minimal.
You need to change the following line of code:
[options setValue:[[NSBundle mainBundle] bundleIdentifier] forKey:NSPersistentStoreUbiquitousContentNameKey];
To something else. What is that something else? I would recommend something descriptive to your application. I have been using class name like structures recently. So I would change it to be the name of your app perhaps or simply “DataStorage”.
The name is unique to your application so the actual value is not important as long as it is understood by you.
So I changed my code below...
options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, // Key to automatically attempt to migrate versioned stores
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, // Key to attempt to create the mapping model automatically
#"TrafficCamNZ_DataStore", NSPersistentStoreUbiquitousContentNameKey, // Option to specify that a persistent store has a given name in ubiquity.
cloudURL, NSPersistentStoreUbiquitousContentURLKey, // Option to specify the log path to use for ubiquitous content logs.
nil];
Refer the line that says TrafficCamNZ_DataStore
it previously had TrafficCamNZ.DataStore
David
I am using a shared container and just had the same error warning popping up. I could fix it by replacing all occurrences of varying cloud identifier strings like:
"$(TeamIdentifierPrefix)com.mydomain.myapp" and
"com.mydomain.myapp" and
"ABCDEF0123.com.mydomain.myapp"
with just this one explicit cloud container string:
"ABCDEF0123.com.mydomain.myapp"
I guess that at some point, Xcode must have updated the entitlements and re-inserted the "$(TeamIdentifierPrefix)", which was wrong due to the shared container. Also, I had forgotten the identifer in code, just like you seemed to have:
NSString *containerId = #"com.YashwantChauhan.Outis";
that should probably be something like:
NSString *containerId = #"ABCDEF01234.com.YashwantChauhan.Outis";
I had the same issue and I am not sure what the issue is or why it is there.
From what I am reading we should be able to use the dots in the containerId.
However, for me it started working by replacing the dots in the containerId with tildes:
i.e.:
NSString *containerId = #"N6TU2CB323~com~YashwantChauhan~Outis";
instead of:
NSString *containerId = #"N6TU2CB323.com.YashwantChauhan.Outis";
Try to use comYashwantChauhanOutis, without the two points.

Resources