Reference website live updating status from App - ios

I have a website: http://www.grandforks.af.mil/library/weathercenter/index.asp
There is a logo on the middle of the page for the current road conditions on base.
The file names for each condition is different by 1 number.
Green is 19
Yellow is 20
Red is 21
I do not have control over this website.
My question is how can I have the current road conditions in an app that I am building display as a reflection of the website? I don't want to have any user input I want the app to be able to pull off of the site. I have tried using UIWebView but I cannot get it to focus on that area of the page. If I could do that it would probably be the better solution.

Ugly solution:
you can download the html of the website, parse it searching the string "http://www.grandforks.af.mil/shared/media/document/AFD-121002-" and get the actual URL (which is something like http://www.grandforks.af.mil/shared/media/document/AFD-121002-019.jpg).
After that, you can load that URL in your UIImageView or (better) discriminate and show your image that is included in the app.
The ugliness depends by the fact that if they change the image's URL, your app stops working.
I would suggest that when the user opens the app, it goes to check your page and eventually download the string your are looking for. Doing so, if the website changes the url, you can manually modify the source without update the app.
I don't know if using others information is legal.
EDIT:
here is an example that I built that demonstrate how you can substring a string:
NSString *myString = #"11111www.the-site.com/img42.jpg222222222222222";
NSString *searchString = #"www.the-site.com/img";
NSRange range = [myString rangeOfString:searchString];
NSLog(#"searched string strart at character %lu, and it's long %lu charactrers", (unsigned long)range.location, (unsigned long)range.length);
NSInteger index = range.location + range.length;
NSString *mySubString = [myString substringFromIndex:index];
NSLog(#"string from the index: %#", mySubString);
//I know that the substring I'm looking for is long exactly 2 characters
NSString *the_answer = [mySubString substringToIndex:2];
NSLog(#"this should print 42: %#", the_answer);
I added some prints, so you can see step by step what I'm doing.
Obviously you have to change "searchString" with "http://www.grandforks.af.mil/shared/media/document/AFD-121002-" and myString is the html of the page.
I hope it helps.

Related

Remove Space After a Particular Character

I have an string which is coming from a server :
<p>(555) 555-5555 </p>
I want to remove any space after teland up to 10 characters.
For removing only spaces between characters you can use this
NSString *strNum = #"(555) 555-5555";
strNum = [strNum stringByReplacingOccurrencesOfString:#" " withString:#""];
Hope this will help you..!! :)
Removing spaces is called Trimming. You can find a possible solution here, or here
Solution copied here in case links break :
NSString *string = #" this text has spaces before and after ";
NSString *trimmedString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
This is slightly better than replacing " " with "", because it uses the charset, and you "never know how white spaces are gonna be in other character sets". The OS does know, so better trust it.
Since your question isn't 100% clear, I'm assuming that is what you need, but feel free to comment for more help :)
EDIT : I might have misunderstood you. If you need to remove all spaces in the string, you could just use Abha's answer.
EDIT 2 : Okay we're about to solve this outstanding mystery.
You want to trim ALL spaces after telinside your string.
What you need to do (and for the sake of learning I'm not gonna write code) is :
Find (using available NSString methods) the word telinside the string. Once you found it, you can find it's index inside the string (after all, a string is just an array of char).
Once you have the index, you just have to use Abha's answer (replace occurences of " " with "") in the range starting with the index you found and ending at that index + 10 (or whatever number you need).
It should be between 2 to 5 lines long, using various NSString methods or, if you really want to, a loop.
Answers you should check for inspiration :
Find string in string
Replace characters in range
Find index of char in string
Though, for the sake of conversation, I'm assuming you only need the phone number (not the tel). So removing ALL spaces should be enough (again, Abha's answer). I don't see any reason why you would take particular care for the first portion of the string when you probably won't use it anyway. Maybe I'm wrong but, you're saying you're new and I'm thinking you're approaching this the wrong way.
Also, to add something else, if you have any control over the server, the server itself should not send tel:(555) 555 5555. That's prone to mistakes. Either the server sends a string to be displayed, with proper characters and nice writing, like Telephone : (555) 555 5555", or you receive ONLY the phone number in a phone object (json or something), like 5555555555. If you have any control over the server, make it send the correct information instead of sending something not practical and having to rework it again.
Note that usually, it's the second option. The server sends something raw, and you just modify it to look good if necessary. Not the other way around.
You need to use NSMutableString class and its manipulation functions provided itself.
NSMutableString *muString = [NSMutableString stringWithString:#"(555) 555-5555"];
[muString insertString:#"" atIndex:10];
Some methods to split your string :
substringFromIndex:
substringWithRange:
substringToIndex:
Edit:
If your string is dynamic and you really dont know the index from where you need to remove extra spaces use below method of NSString class:
stringByReplacingOccurrencesOfString: Returns a new string in which all occurrences of a target string in the receiver are replaced by another given string.
Example:
NSString *yourStr = #"(555) 555-5555"; // needs to remove spaces and all
yourStr = [yourStr stringByReplacingOccurrencesOfString:#" " withString:#""]; // after manipulation
Or if you really need to do some more advance changes into your string use NSMutableString class see detail below and example above on the top:
NSMutableString: The NSMutableString class declares the programmatic interface to an object that manages a mutable string—that is, a string whose contents can be edited—that conceptually represents an array of Unicode characters. To construct and manage an immutable string—or a string that cannot be changed after it has been created—use an object of the NSString class.
So you want to remove space from first 10 character, which you think is a tel number, right?
So make a sub string and replace space from that.
NSString *str = #"(555) 555-5555";
NSString *firstPart = [[str substringToIndex:10] stringByReplacingOccurrencesOfString:#" " withString:#""];
then take the second part and merge it.
NSString *secondPart = [str substringFromIndex:10];
NSMutableString *finalString = [NSMutableString stringWithFormat:#"%#%#",firstPart,secondPart];
Is this what you want to do? I've written in step by step for better understanding.
This solution in not generic but may work on your condition
NSString * serverString;
NSArray* stringComp = [serverString componentsSeparatedByString:#"\\"];
NSString* stringOfTel = [stringComp objectAtIndex:1];
NSString* withOutSpaceTel = [stringOfTel stringByReplacingOccurrencesOfString:#" " withString:#""];
serverString = [serverString stringByReplacingOccurrencesOfString:stringOfTel withString:withOutSpaceTel];
and your will get your serverstring with space you want.
Again this may work only for your current solution.
NSString *string = #"(555) 555-5555" //here you need to assign string which you are getting from server
NSString *resultString = [string stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceCharacterSet]];
resultString will be the string with no space at start and end of the string.
Hope this helps!

How to select a sub-string from an NSString using a key word?

I had written a code snippet which writes the contents of a textfield to a file. Unfortunately my code, depending on the OS, writes the file path differently
In Yosemite, The path is
file:///var/folders/qg/....../myfile.txt
While in mountain lion the path is
file://localhost/var/folders/yx....../myfile.txt
I have an API which takes the file path as /var/folder/xx/...../myfile.txt
I was wondering if there is a way to make a substring from /var/.. till the end of the path.
You could do something along the following:
// Lets say pathString is an NSString of the path
NSRange varRange = [pathString rangeOfString:#"/var/"];
NSString *correctPath = [pathString substringFromIndex:varRange.location];
In the above example, you use NSString's instance method rangeOfString: to receive the range of the wanted substring, which in this case is /var/, and store it into a range variable.
Then you create a new NSString variable, using the original pathString, with the use of the instance variable substringFromIndex, which returns a new substring, which start at the index you choose, and ends at the end of the string (which you provide the range location we've received, to identify where /var/ begins).
Good luck mate.
If file path is store in NSString *yourPathString, then
NSString *resultString= [yourPathString substringFromIndex:[yourPathString rangeOfString:#"/var"].location]];
NSLog(#"Final result : %#", resultString);
Try this code, hope it helps.
Depending on how you're calling your resource, how it needs to be saved, and what that API is looking for, you'll want to use NSURL methods, not strings. Specifically, it sounds like you'll be most interested in using absolutePath, relativePath, resourceIdentifierand pathComponents
I would recommend reading the URL Loading System guide by Apple or NSHipster's article for a more human readable answer.

cant get 100,000+ hebrew characters into objective-c string

I have 100,000+ characters of text that need to be converted into a string so I can count the characters and display them on a page correctly, but in the text there are tons of quotations ("") and lots of commas, so it doesnt even turn into a string.
Does anyone know a way that you can ignore quotations and commas inside a NSString without having to do this \"" each time?
Here's some of the text. its english/hebrew
Psalm 30
...
Psalm 100
...
The following Psalm is not to be said on Shabbat, Festivals, the day before Pesach, Chol HaMoed Pesach, and the day of Yom Kippur
...
You say “I cant even turn the text into a string”. Since you said (in a comment) you're “just pulling it off this website”, the simplest way to do this is +[NSString stringWithContentsOfURL:encoding:error:]. This works for me:
NSURL *url = [NSURL URLWithString:#"http://opensiddur.org/wp-content/uploads/2010/08/The-Blessing-Book-Nusa%E1%B8%A5-Ha-Ari-%E1%B8%A4aBaD-3.2.txt"];
NSError *error;
NSString *text = [NSString stringWithContentsOfURL:url usedEncoding:nil error:&error];
NSLog(#"error=%# text.length=%lu", error, (unsigned long)text.length);
You can look into NSURLSession or NSURLConnection when you want to do it in a non-blocking fashion.
If you plan to distribute the text in a file (named, let's say, “blessingBook.txt”) in your app bundle, you can get the URL this way:
NSURL *url = [[NSBundle mainBundle] URLForResource:#"blessingBook" withExtension:#"txt"];
If you're loading it directly from your app bundle, you probably don't need to worry about using NSURLSession to load it in the background. You might want to do your “processing” in the background though, if it takes a while.
You can replace the punctuation or commas or what ever you want to #"" (empty string).
yourString=[yourString stringByReplacingOccurrencesOfString:#"," withString:#""];
yourString=[yourString stringByReplacingOccurrencesOfString:#":" withString:#""];
yourString=[yourString stringByReplacingOccurrencesOfString:#";" withString:#""];
What ever the text you want to replace. Replace as above.
But it is lengthy process finding un wanted quotations, commas..some characters and replace with empty string..
Hope it helps you..!

Why am I unable to post to Twitter using SLComposeViewController?

I'm trying to post an article title and an article URL to twitter and then append the app's name to the end of the tweet. So something like
"How to grow a cactus (via #appname)" attached URL
I was having trouble figuring out how to balance the length of the title and URL to make sure that the tweet doesn't exceed 140 characters. So if the URL is really long, cut some of the article title off so it can be under 140 characters.
Looking at Twitter's guidelines for SLComposeViewController they state this part:
Note that the methods for setting initial content respond with Boolean values; this allows you, the developer, to not have to worry about the current count of characters in the body of the Tweet that you are initializing. If the method returns YES, there was enough room to add the content. If the method returns NO, the content you attempted to add would result in a Tweet longer than 140 characters. The logic for character counting also takes into effect the current number of characters required for t.co URL wrapping.
(From the "Code Example" section.)
Given that, I wrote the following code to build a tweet and balance the URL length and article length:
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
SLComposeViewController *twitterViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
[twitterViewController addURL:[NSURL URLWithString:self.article.url]];
NSString *titleToShare = self.article.title;
while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]]) {
titleToShare = [titleToShare substringToIndex:titleToShare.length - 1];
}
[self presentViewController:twitterViewController animated:YES completion:nil];
}
Which basically adds the URL then constructs the rest of the tweet by looping through the setInitialText: method until it returns YES, decreasing the length of the title by 1 each time it returns NO in order to get closer to the required length.
But it never returns YES! Even when I know it should. I was using one article where it could potentially exceed 140 characters as the title is 105 characters long and the URL is 55, plus the app credit. So it should theoretically be able to shorten the title down and then add it fine, but it never happens.
So what's going on? How do I accomplish link attachment with SLComposeViewController?
while ([twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
=>
while (![twitterViewController setInitialText:[NSString stringWithFormat:#"%# (via #SyllableApp)", titleToShare]])
There is a ! missing in condition, so you shorten the post when it fits, not when it is too long ;)
The problem with this approach is that it works only on iOS6.
SLComposeViewController *social = [[SLComposeViewController alloc] init];
NSString *stringToShare = #"";
for (int i = 0; i < 150; i++)
{
stringToShare = [stringToShare stringByAppendingString:#"x"];
}
NSLog(#"%#",[social setInitialText:stringToShare]?#"YES":#"NO");
yields different results on iOS6 (NO) and iOS7 (YES). The answer to this behaviour comes from the documentation of SLComposeViewController
// Sets the initial text to be posted. Returns NO if the sheet has already been
// presented to the user. On iOS 6.x, this returns NO if the specified text
// will not fit within the character space currently available; on iOS 7.0 and
// later, you may supply text with a length greater than the service supports,
// and the sheet will allow the user to edit it accordingly.
- (BOOL)setInitialText:(NSString *)text;
Probably is worth either having different approaches on iOS6 and 7, or check the length without using SLComposeViewController method.
As imihaly said, you did miss a "!".
And 140 characters count is the limit of title only, not including URL.So your title is 105 characters long which is less than 140,this method should return YES.
There is an open bug with link lengths not getting calculated correctly (radar://10469407). This might be related. You might try sending a Tweet with a link in it to check which URL shortener is being used (I imagine it's using t.co, but I could be wrong).

iOS: sending .jpg image as base64 to tcp server

This one is going to kill me. I'm so close to getting this done except for this one stupid problem. And I am not sure I will be able to adequately describe the problem, but I'll try.
My enterprise app uses the iPhone camera to take pictures of receipts of purchases made by our field personnel. I used a real cool API for turning the jpeg data to base 64 (https://github.com/nicklockwood/Base64) to send via TCP connection to the VB 2010 server, which reads it as a text string and converts it back to a binary.
When the base64 file is created, it is first saved to disk on the phone, because there may be more images. Then when ready to send, the process will read each base64 file and send it one at a time.
The text string created by the base64 function is quite large, and at first it was only sending about 131,000 bytes, which would convert back to binary easily enough but would render about 1/4 to 1/3 of the image. I just figured that the data was being truncated because the app was trying to get ahead of itself.
So then I found a nice snippet that showed me how to use the NSStreamEventHasSpaceAvailable event to split the base64 string into several chunks and send them sequentially. (http://www.ios-developer.net/iphone-ipad-programmer/development/tcpip/tcp-client) That works great insofar as it sends the full file -- that is, the resulting file received by the server is the correct size, the same as the base64 file before it's sent.
The problem here is that at some point the file received by the server is corrupted because it seems to start all over at the beginning of the file... in other words, the data starts to repeat itself.
The odd part is that the repeating part starts at exactly the same spot in the received file every time: at position 131016. It doesn't start the repetition at the end of the file, it just interrupts the file at that point and jumps back to the beginning. And it happens that that was the size of the file that was sent before I started using the HasSpaceAvailable event. I can't figure out what the significance of the value 131,016 is. Maximum buffer size somewhere?
Using all kinds of NSLogs and breakpoints, I have pretty much determined that the data is leaving the phone that way, and not being scrambled by the server. I also wrote in an NSMailComposeViewer method that would email me the base64 file as an attachment, and it comes through perfectly.
Here is the code for when the file is read from disk and sent to the server:
int i;
for (i = 0; i < [imageList count];i++){
NSArray *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory= [documentsPath objectAtIndex:0]; //Get the docs directory
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:imageFileName];
imageFileName = [imageList objectAtIndex:i] ;
NSLog(#"Image index: %d - image file name: %#",i,imageFileName);
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imagePath];
if(fileExists == YES){
NSString *imageReceipt = [NSString stringWithContentsOfFile:imagePath encoding:NSASCIIStringEncoding error:nil];
int32_t imageStringLen = [imageReceipt length];
NSString *imageSize = [NSString stringWithFormat: #"%d",imageStringLen];
NSString *currentImage = [NSString stringWithFormat:#"image,%#,%#,%#",imageFileName,imageSize,imageReceipt]; //creates a CSV string with a header string with the filename and file size, and then appends the image data as the final comma-separated string.
data = [[NSMutableData alloc] initWithData:[currentImage dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
And then here is the code that uses the HasSpaceAvailable event:
case NSStreamEventHasSpaceAvailable:
if (data != nil)
{
//Send rest of the packet
int ActualOutputBytes = [outputStream write:[data bytes] maxLength:[data length]];
int totalLength = [data length];
if (ActualOutputBytes >= totalLength)
{
//It was all sent
data = nil;
}
else
{
//Only partially sent
[data replaceBytesInRange:NSMakeRange(0, ActualOutputBytes) withBytes:NULL length:0]; //Remove sent bytes from the start
}
}
break;
(I especially like this code because it would allow placing a ProgressView control on the screen.)
The network stream event handler code is in the root view controller, but the image data in base64 is being sent from another view controller. My instinct tells me that this is not a problem because it has worked fine until now, but with much shorter strings.
Now, there's one other issue that may be related -- and probably is. I can't seem to complete the transfer of the data unless I close the app. The server doesn't see it until the connection is closed, I guess. I have tried placing [outputStream close] in various places in the code to no avail. I've also tried terminating the base64 string with a linefeed or carriage return or both.
The server is programmed to save the file when it has seen the correct number of bytes, but that never happens until the app is closed. I know by using WireShark on the server that some of the data is being received, but the remaining data, as I have said, doesn't arrive until the app is closed.
I suspect that this last part (completing the transfer) is the problem, but for the life of me, I can't find anything online that addresses this, unless I am just too ignorant to know what search terms to use.... which is highly likely.
I hope I have given enough information. Can anyone help me?
EDIT
The solution to the problem appeared to be different than what was suspected in the original answer. Through the discussion in the comments the QP has been led to a solution. Here is a summary:
The transmission of data through a raw TCP socket requires thorough handling of the enqueing logic, which was not properly taken into account by the QP. I recommended to use the socket library CocoaAsyncSocket which handles this part of the task and which in turn led the QP to a working solution.
Original Answer:
I'd guess NSString is not up to the task. It's made to hold, well, strings.
Try to read the file into an NSData directly instead and sending it as binary. (Its ascii in the end, isn't it?) Besides, this will be much more resource friendly than your current code.

Resources