How to read, separate, and use input data - objective-c

I'm trying to develop an iOS app that will basically act as a GUI for a telnet session. I have finally gotten the NSStream coding to work (mostly) and now I'm trying to figure out how to create certain events based on code results. I think the way to do this would be to examine the results and run a "predicate" on them. Simple example below:
I press a button that sends a command, for example the command:
"info"
The server sends a response (which I'm currently snagging and writing in my NSLog):
Version: 1.1.1
Model: xyzabc
Whatever: whatever
Etc: etc..
How would I be able to pull that information, read it, and just take the "1.1.1" or the "xyzabc" and add it to a label in my VC?
I don't need the basics of how to add it to the label, just how to strip the correct information and stick the values into an NSString.
Thanks in advance,
Chuck
(total iOS coding NOOB)
(Edit, some code added):
if (nil != output) {
NSLog(#"%#", output);
[self messageReceived:output];
_txtLabel = output;
-(void)messageReceived:(NSString *)message {
[_messages addObject:message];
}
_txtLabel is a NSString
_messages is a NSMutableArray
oh, and the NSLog looks like this when it comes in, not sure if this is relevant..:
2014-06-27 15:22:07.930 multiSceneTest[37480:60b] Version: 1.1.1
2014-06-27 15:22:07.930 multiSceneTest[37480:60b] Model: xyzabc
2014-06-27 15:22:07.931 multiSceneTest[37480:60b] Whatever: Whatever

Related

Cannot use removeObjectForKey in Parse (using Back4App on Objc)

I'm using Back4App's service to host Parse server and I can't seem to successfully remove a field from a row. The field in question is a pointer to another object, and calling removeObjectForKey followed by a save does not work. Other updates work in the same batch, and I have seen that 4 times out the 36 that I have tried, it did successfully delete the object.
[self.myProfile removeObjectForKey:#"partnership"];
[self.myProfile saveEventually:^(BOOL succeeded, NSError * _Nullable error) {
NSLog(#"success %d", succeeded); //always returns true
}];
Is this a known problem with Back4App? Or Parse itself? I tried the same code in swift and it worked.
Any ideas?
When you need to run a callback, to confirm when is deleted, is recommended the deleteInBackgroundWithBlock: or deleteInBackgroundWithTarget:selector: methods. You can delete a single field from an object with the removeObjectForKey method:
// After this, the playerName field will be empty
[classScore removeObjectForKey:#"customName"];
// Saves the field deletion to the Parse Cloud
[classScore saveInBackground];
About the saveEventually, most save functions execute immediately, and inform your app when the save is complete. If you don’t need to know when the save has finished, you can use saveEventually instead. The advantage is that if the user currently doesn’t have a network connection.
Content from Parse =D

Encode PNG for delivery via JSON to Objective C/iOS device suddenly not working

SOLVED
There was an exercise in futility.
24 hours to discover it was a comma in the wrong place.
#sysMessage.messagePictureData = Base64.strict_encode64(open(imagestring).read),
#sysMessage.messagePuzzleNumber = "#{sendPiece}"
Two things concatenated and hours lost. Thanks to those who read this.
UPDATE
I now seem to have the files being read and encoded "properly" ... in that I'm seeing what I'm expecting in terms of encoded data. But I have no idea why the JSON is coming down enclosing the data in square brackets and quotes (and adding another value!).
messagePictureData = "[\"iVBORw0KGgoAAAANSUhEUgAAANgAAADYCAYAAACJIC3tAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAMSZJREFUeNrsnQmcFOWZ/9/qqr67p+e+mJPhmINBjhkYAQFFUMEo4JGN2Rz6j8lqotnsJqtxs6sxnzWa7Gpi1jMbNcb7wFsEuQTkZm ... [LOTS OF DATA] ... JZlUmyRSYkV+5NtGf5B2KdORE1ZLMK1kCCkD5oF1I8Pl+gu22gftAT7u4/1+AiwEhfhIPFXJaMLpvZFUlRMzsUNWIyMqs/QcwcTDKlBdsNrcHOwSZ13bQd2rn49yfASGdVDzofwWIHPsXy+PDylRK1g5FIBBiJRICRSKRPyME0+klIJHIwEmlM6P8LMACzov3UuDGSEwAAAABJRU5ErkJggg==\", \"30\"]";
How do I get Objective C to just read the first part in the brackets? I'm drawing a complete blank!
ORIGINAL POST
I'm sure there are better ways, but I have a Rails Server which was encoding PNG image files from AWS and, using RABL, encoding them into JSON (with a lot of other data) which was being delivered to my iOS device and being saved as a photo in Core Data.
It was all working, but now it's not and I am wondering if someone could take a look and see where it's going wrong. Sadly, I did a bundle update on my computer and this has updated a LOT of gems and Rails itself. Sigh. I consequently have no idea if there is a problem with one of the gems (and not a highly proficient debugger to try and sort it out) or my code.
Rails Controller code:
The code looks if there is a photo held on AWS. If there is, it looks for the URL, or provides a placeholder image URL if there isn't an image. I then need it to read the file and store it in a the database for delivery.
if (#photos.approvedMainPhoto == true)
imagestring = eval "#photos.photoImage#{sendPiece}.url"
else
imagestring = "#{::Rails.root}/public/images/placeholders/smallimageplaceholder.png"
end
#sysMessage = Message.new
...
#sysMessage.messagePictureData = File.open(imagestring, "r").read,
...
if (#sysMessage.save)
[true, #sysMessage.id]
else
[false, 0]
end
RABL Code
I've stripped some of the code out but I have coded that if there is picture data (and there isn't always going to be a photo), then encode it using Base64.strict_encode64 what is held in the database for transport.
object false
node(:message) { #code }
node(:number) { #nummessages }
child #messages, :object_root => false do
node(:messagePictureData, :if => lambda { |m| m.messageText == ""}) do |m|
Base64.strict_encode64(m.messagePictureData)
end
end
This seems to be delivering something. When I ask for the output in my XCode Console ... I get something similar to:
The JSON encoded data is saying:
messagePictureData = "WyJceDg5UE5HXHJcblx1MDAxQVxuXHUwMDAwXHUwMDAwXHUwMDAwXHJJSERSXHUwMDAwXHUwMDAwXHUwMDAwXHhEOFx1MDAwMFx1MDAwMFx1MDAwMFx4RDhcYlx1MDAwNlx1MDAwMFx1MDAwMFx1MDAwMFx4ODkgLVx4RURcdTAwMDBcdTAwMDBcdTAwMDBcdTAwMTl0RVh0U29mdHdhcmVcdTAwMDBBZG9iZSBJbWFnZVJlYWR5cVx4QzllPFx1MDAwMFx1MDAwMDEmSURBVHhceERBXHhFQ1x4OURcdFx4OUNcdTAwMTRceEU1XHg5OVx4RkZceERG6qq .... [LOTS MORE] ... HhDMWJcYT5ceEM1XHhGMlx4RjhceEYwXHhGMlx4OTVcdTAwMTJceEI1XHg4M1x4OTFIXHUwMDA0XHUwMDE4XHg4OURceDgwXHg5MUhceEE0T1x4QzhceEMxNFx4RkFJSCRyMFx1MDAxMmlMXHhFOFx4RkZcdjBcdTAwMDBceEIzXHhBMlx4RkTUuDFceDkyXHUwMDEzXHUwMDAwXHUwMDAwXHUwMDAwXHUwMDAwSUVORFx4QUVCYFx4ODIiLCAiMzAiXQ==";
When I put it through the following code in Objective C:
Objective C Code:
NSLog(#"I have the message Picture Data as: %#", message[#"messagePictureData");
NSData *photo = [[NSData alloc] initWithBase64EncodedString:message[#"messagePictureData"] options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSLog(#"I have the photo data as: %#", photo);
I get the following output in the Console:
I have the photo data as: <5b225c78 3839504e 475c725c 6e5c7530 3031415c 6e5c7530 3030305c 75303030 305c7530 3030305c 72494844 ... [LOTS MORE] ... 3839445c 7838305c 78393148 5c784134 4f5c7843 385c7843 31345c78 46414948 2472305c 75303031 32694c5c 7845385c 7846465c 76305c75 30303030 5c784233 5c784132 5c784644 d4b8315c 7839325c 75303031 335c7530 3030305c 75303030 305c7530 3030305c 75303030 3049454e 445c7841 4542605c 78383222 2c202233 30225d>
It say's that it's saving the image in Core Data. However, what I'm getting are transparent squares and not photos.
And, every so often, when it's trying to get a slice from AWS, I get the following log error ... which also means nothing to me!
WARN: No such file or directory # rb_sysopen - https://XXXXXXXXXX.s3-ap-southeast-1.amazonaws.com/uploads/photo/photoImage20/77/photoImage20.jpg ... [lots more]
When I place the complete URL pointing to Amazon into Safari, it shows the photo perfectly. Sigh.
Any help would be gratefully received as, once again, I'm stumped.
There was an exercise in futility.
24 hours to discover it was a comma in the wrong place.
#sysMessage.messagePictureData = Base64.strict_encode64(open(imagestring).read),
#sysMessage.messagePuzzleNumber = "#{sendPiece}"
Two things concatenated and hours lost.
Thanks to those who read this.

ffmpeg code (API)

I started to deal with ffmpeg API ( not the command prompt ) to build a movie editor, and I'm trying to find a good tutorial about how to extract keyframes from video, but I didn't find it.
Someone did it before and can write the code here?
Someone has a good tutorial about ffmpeg API?
Thank you!
In your demuxing loop, check for the AV_PKT_FLAG_KEY flag in AVPacket::flags after calling av_read_frame() with your AVFormatContext and confirming the read packet is from the correct stream of the input. Example:
AVPacket packet;
if (av_read_frame(pFormatCtx, &packet) < 0) {
break;
}
if (videoStream/* e.g. 0 or 1 */ == packet.stream_index) {
if (packet.flags & AV_PKT_FLAG_KEY) { //do something
Note that, in my experience, you sometimes need to decode up to 2 keyframes before the desired frame in order to produce a good picture.
See the doc/examples directory in the ffmpeg distribution for some API usage examples, e.g. demuxing_decoding.c. You can also reference ffmpeg.c (the source of the famous CLI) if you are brave and/or have a good IDE.

Why does my core data object not show up using fetch requests between related objects that were created in the same session?

This is a really weird situation which I have been battling to resolve over the last couple of days.
I have a Card entity with a To-Many relationship on a Transaction entity. I am also using Magical Record to remove the boilerplate code around managing my data store.
My problem occurs in the following order:
Create a Card object
Then create a Transaction object in another view
When I inspect the transaction count with [card.transactions count] I get 1 as the size
However, if I perform a fetch request using the same context the transaction is not there. My predicate looks like this:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"card == %# && deleted == 0", card];
So logic says that I am perhaps not saving the context after saving the transaction, but the weird thing is that if I quit the app and then rerun it, the transaction is there. Steps 1-4 work perfectly too if I create the card, quit the app and then run the app and add a transaction. Then my save transaction code works fine.
So my question is, why aren't my objects showing up using fetch requests on a newly created parent object, where "newly created" means that it was created in the same session as the child object.
My code for creating the card looks like this:
GYCard *card = [GYCard MR_createInContext:[NSManagedObjectContext MR_defaultContext]];
[[NSManagedObjectContext MR_defaultContext] MR_save];
Then when I save the transaction my code looks like this:
NSManagedObjectContext *localContext = [NSManagedObjectContext MR_defaultContext];
NSNumber *transactionAmount = [self.numberFormatter numberFromString:self.transactionAmountLabel.text];
GYTransaction *transaction = [GYTransaction MR_createInContext:localContext];
transaction.amount = transactionAmount;
transaction.deleted = [NSNumber numberWithBool:NO];
transaction.card = self.card;
[localContext MR_save];
The code that is not working is this:
+ (int) countTransactions:(GYCard *) card {
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"card == %# && deleted == 0", card];
return [GYTransaction MR_countOfEntitiesWithPredicate:predicate inContext:[NSManagedObjectContext MR_defaultContext]];
}
The countTransactions always returns 0 if the card was created in the same session. But it works 100% if I quit the app and relaunch. It also works for adding any new transactions to the card after quitting and relaunching the app.
This appears to be a Magical Record issue. I was using the 2.0 beta branch of Magical Record and after reverting to the tagged version:1.8.3 the issue disappears. So 2.0 seems to be the culprit. It would still be interesting to know however, why version 2.0 is causing this problem.
I would strongly advise anybody who is using Magical Record to avoid the 2.0 branch until it comes out of beta.
Update: After further investigation what the 2.0 beta of Magical Record was doing was generating 2 save notifications for 1 save, this led to my app inadvertently have 2 versions of the card. This resulted in causing the transaction that I was logging to be logged on the first card but the second card obviously did not have a transaction on it. My fetch request was then fetching the second card and returning zero transactions. Quitting and restarting the app then made my app load the correct transaction from the data store and thus worked as expected.
This could be related to the includesPendingChanges property on NSFetchRequest. However the default for this is YES which means any unsaved changes should be included in any queries.
I'm not sure what the MR_ methods are doing under the hood, but the setIncludesPendingChanges: documentation states:
Special Considerations
A value of YES is not supported in conjunction with the result type
NSDictionaryResultType, including calculation of aggregate results
(such as max and min). For dictionaries, the array returned from the
fetch reflects the current state in the persistent store, and does not
take into account any pending changes, insertions, or deletions in the
context.
So I would make sure the MR_countOfEntitiesWithPredicate method is not doing anything funky. Maybe try calling the standard - (NSUInteger)countForFetchRequest:(NSFetchRequest *)request error: (NSError **)error method on your context and see what that returns.

Simplest way to get the PID of a recently launched application

I want to launch a file with a specified application, and I want the launched program to immediately become the frontmost window.
I know that I can do this as follows:
[[NSWorkspace sharedWorkspace] openFile:fileName withApplication:appName];
Then, if I can get the PID of that launched application, I can then do this to make that application frontmost:
NSRunningApplication* app = [NSRunningApplication
runningApplicationWithProcessIdentifier: PID];
[app activateWithOptions: NSApplicationActivateAllWindows];
The question I have is this: what is the simplest, quickest, and most reliable way to get this application's PID right after launching, so I can make sure that this application is frontmost?
This is not as straightforward as it might appear at first glance. For example, I need a process name in order to get the PID using Carbon calls, or via the application dictionary that is accessible via NSRunningApplication. However, in the general case, I don't always know what the process name is, and in some cases, the process name is an empty string.
Furthermore, I might have other instances of this same application already running, and I want to always get the PID of the specific instance of the application that I just launched.
Can anyone suggest a definitive, 100-percent reliable way to get the currently launched application's PID?
Or alternatively, is there a way to launch a given file with a specified application such that the application always opens as the frontmost app?
Have you tried using the other version of openFile which will allow you to deactivate your application, allowing the new application to take focus?
[[NSWorkspace sharedWorkspace] openFile:fileName withApplication:appName andDeactivate:YES];
It is definitely not easy to get the PID of an application. And that's how Apple likes it.. Those cheeky bastards.
I had to write this beast just to get the PID from a full path of an app I knew was running.. Hey it's easier than parsing ps aux !
Sorry if there are some of my own private functions in there but you can get the idea of how I went about it and what I tried to avoid along the way.
+ (NSUInteger)pidFromAppPath:(NSString*)path
{
NSRunningApplication *n = [[[NSWorkspace sharedWorkspace]runningApplications] filterOne:^BOOL(NSRunningApplication *runner) {
// optional: avoid totally faceless apps and "Desk Accesory"-type background apps.
if (runner.activationPolicy == NSApplicationActivationPolicyProhibited) ||
runner.activationPolicy == NSApplicationActivationPolicyAccessory)
return nil;
id runPath = [runner valueForKeyPath:#"bundleURL"];
NSString *runString = [runPath isKindOfClass:[NSString class]]
? runPath
: [runPath isKindOfClass:NSURL.class] ? [((NSURL*)runPath) path]
: nil;
// optional: filter out Google Chrome's mockery of a once sane process-table
if ( !runString
|| [[runString lastPathComponent]contains:#"Google Chrome Helper.app"]
|| [[runString lastPathComponent]contains:#"Google Chrome Worker.app"]
|| [[runString lastPathComponent]contains:#"Google Chrome Renderer.app"] )
return nil;
return [runString isEqualToString:path] ?: nil; // This is where you actually test to see if it's the same as the string passed in, lol.
}];
return n ? [n processIdentifier] : 11000; // if 11000 you messed up.
}
And voilá... NSLOG: Pid of /Applications/Utilities/Terminal.app is 46152