Parsing HTML content to use with iPhone app - iphone

I don't even know if the title for this question is appropriate, since I'm really lost and need some advice, a starting point to what I need to accomplish.
My iPhone app plays audio streamed from the Internet, with my custom made player. Some links are live streams from Akamai and others are audio files stored on a website. I'm OK with the live streams, but my problem is with the audio files.
As I have many stored audio files that the user can choose from, in different languages, and I don't want to hardcode all of them on my application.Then I need a clever way for the user to browse on the app (pushing the information from the Internet) until he reaches the desired file to play.
The website is organized like this:
First there is list, having all available programs. The user chooses the desired program, then another page shows up and he has to choose a day of the week to play.
My question is: how can I parse this content, with programs and days of the week to choose from? Should I look into HTML parsing? Is there a better/simpler way, like making XML files on the website?
If this helps, the all the webpages end with the .aspx extension.
Please, any advise from a more experienced programmer will greatly help me. Thank you!

I don't think parsing HTML would be the best implementation here. Go for a structured source that doesn't have viewable markup to worry about parsing out or ignoring altogether (also will mean fewer resources thrown at parsing the markup because you will only be parsing what matters).
I'd suggest consuming an XML or JSON source that can be converted to a NSDictionary or other data structure for app use. Here's a neat little class that converts an XML source to an NSDictionary: http://troybrant.net/blog/2010/09/simple-xml-to-nsdictionary-converter/
TBXML is another light-weight XML parser for Objective-C that makes implementing a custom data object up to you: http://www.tbxml.co.uk/
If you'd rather use JSON, there are a number of helpers out there. A good place to start looking would be here: http://cocoaobjects.com/?s=json
If I have understood your question correctly, whatever source you choose, you're likely to want to wind up with a dictionary object that looks something like this:
programs = (
{
program_name: "Foo";
tracks = (
{ day: Monday;
track: audio_file1.mp3;
},
{ day: Tuesday;
track: audio_file2.mp3;
},
{ day: Wednesday;
track: audio_file3.mp3;
}
);
},
{
program_name: "Bar";
tracks = (
{ day: Monday;
track: audio_file4.mp3;
},
{ day: Tuesday;
track: audio_file5.mp3;
},
{ day: Wednesday;
track: audio_file6.mp3;
}
);
},
{
program_name: "Baz";
tracks = (
{ day: Monday;
track: audio_file7.mp3;
},
{ day: Tuesday;
track: audio_file8.mp3;
},
{ day: Wednesday;
track: audio_file9.mp3;
}
);
};
);
Once you've worked out your data source, and converted it to a native data object for working with in Obj-C, you should be able to proceed with coding up a UI that can iterate through the dictionary to provide a list of programs and, in turn, a list of days for each program with accompanying audio files to select to play.

I had a similar need. Consuming data from an ASP.NET site. In the end I used JSON from the .NET side and return JSON. Then, I used the json-framework from Google Code to convert the JSON returned to an NSDictionary. From there the rest is history.
If you are using .NET MVC, then returning JSON results is super simple in a controller. Since you have aspx extensions, I assume that is not the case. There are tons of JSON parsers for C# listed at the bottom of the json.org homepage.

if the website content is static, I would hard code the file names and appropriate URL's to your server within the app and let the user scroll through the list of available items.
if the website content changes, then I would create an XML file on a server which your app downloads on launch (or as you deem fit) and parse within the app, then continue as per static content.
hope this starts you off in the right direction.

Think outside the box: use UIWebView
How about instead of thinking how to parse data and then write UI code to display it we think more of the big picture: we want to present to iPhone user sequence of screens to select and play a recording, and this should be coming from a web server. Only if there was such a tool... but wait, there is! It's called web browser and in the form of UIWebView you can integrate it in your interface, with a little twist.
First, adding UIWebView is very easy, check this http://zpasternack.blogspot.com/2010/09/stupid-uialertview-tricks-part-i.html for illustration.
So let's say we added web view and user can select an audio file from there, what happens then? Turns out you can tell it what should happen, check this question UIWebView open links in Safari . You can hook your code into handling of link clicks and do whatever you please (like hide web view and show player etc).
To give an example, say first in the web view you load
http://foobar.com/somepath/listOfPrograms
which happens to be web page showing list of the programs (which thanks on some clever CSS could look just like an UITableView if you please). User clicks on a programing name, that goes to
http://foobar.com/somepath/programs/CarTalk
which page presents list of weekly shows (again iPhonesque formatted) and when clicked on a link, this now points to
http://audio.foobar.com/somesuch/45678913.mp3
at which point your code recognizes that's audio URL, apprehends control and plays it however it pleases.
How useful is that you may wonder. The answer is "very" :-). It moves the presentation structure away from the app - and to the web server. The app's entry into the UIWebView is the initial URL and the exit is click on audio file link. In a few months someone decides they want the choices not to be made fist programming name and then day of the week; or add additional layer of choice by language or country. No problemo, no need to release new version of the app, just tweak a bit the web pages on the server and the app will pick it up automagically.
It also makes testing the web server side easy - just point any browser to the initial page URL and click-through to see if you make it to a viable audio file. The web master can handle that independently of you, the app writer. You don't even have to care what they use on their side to get those pages, is it hard-coded in html, or comes from a SQL DB, XML tarpit, whatever.

If it were me, and assuming I have some clue as to what you're talking about, I would have a database that shows the relationship between the audio content and the date. Then your spinner for the content would just be updated by a query...
So, for instance, assume a table
+----------------------------------------------------------------------+
| Filename | Language | Date |
+----------------------------------------------------------------------+
| kjslfiewofksalfjslfakj | Swahili | 2011-11-01 |
| shfaahflajfewifhlanfww | Guyanese | 2011-10-08 |
| weijalfjlajfljalsfjewn | French | 2011-11-01 |
| fiwojancanlsjfhkwehwlk | Swahili | 2011-11-01 |
| fhalksflwiehlfnaksflhw | Swahili | 2011-11-03 |
+----------------------------------------------------------------------+
Okay, so if joe schmo reaches the page for the show dated 2011-11-01 and his language is Swahili, two rows will be returned:
+----------------------------------------------------------------------+
| Filename | Language | Date |
+----------------------------------------------------------------------+
| kjslfiewofksalfjslfakj | Swahili | 2011-11-01 |
| fiwojancanlsjfhkwehwlk | Swahili | 2011-11-01 |
+----------------------------------------------------------------------+
You could also easily add references for the date and language that indicate an Akamai record. It doesn't strike me as terribly complicated, but it may mean significant redesign for you. However, you've been purposefully vague on details, so hopefully at least this points you in a right direction.
Edit:
Alright, so after re-reading, there may be a relatively easy way to control content in its organization by using directory structures, but it takes a backseat to my proposed table.
As I understand it, there are potentially three categories at work: program, date, and language.
If I create a file structure (assuming root):
/public_html/audio/[date]/[language]/[program_name].mp4
Then, when the user selects a date and language, we might have:
/public_html/audio/2011-11-14/swahili/the_linux_show.mp4
Then, all we'd have to do is have the $_POST data from the selectors read to provide the show... Unfortunately, this will mean that we have to know the date that the show aired, then language, then show name. This would be a far worse way than a database, but could be done. Use ASP to read directory contents and you can list using loops. Seems pretty simple, but not at all elegant.

Related

Modifying MP3 file header text info

Is there a method I can use in a program to access and modify ripped music CD-MP3 file(s) header text?
There is a method available in the MusicMatch jukeboks music player, but with 2000 files ripper from 50 CD's, the job is quite formidable and the tool "supertagging' is cumbersome to use.
What I see for me is more like the visual representation of Excel, where I would have just the three fields Artist name, Song title and Album name. displayed.
The Artist field would have the option of repeating the top field down for all the song titles, Album would always be repeted for all song titles.
Song titles wil of course have to be entered for each item.
In the ripped files, every file has the fields track#, artist, album + some of less importance.
Just let me know if I am at the wrong forum for my search. I just don't know anywhere else that I might go.
For programming I might use Visual Foxpro and/or assembler. I haven't used C since early 1980's.
If you really want to develop it yourself, at least use an ID3 library, don't write the functionality yourself!
A good one is at http://id3lib.sourceforge.net/. I haven't tried it recently, but I'm sure you can call it from VFP somehow.
If you just want something that is better for tagging a shed-load of files, look at MediaMonkey.
If you want to work solely in VFP then you should use the VFP low-level utilities
FOPEN()
FCHSIZE( )
FCLOSE( )
FCREATE( )
FEOF( )
FFLUSH( )
FGETS( )
FPUTS( )
FREAD( )
FSEEK( )
FWRITE( )
These are pretty well documented within the VFP Help system and there are numerous examples on the web.
With them you can get the 'raw' data from the MP3 file, identify what you are looking for, change it, and write it back again.
The downside is that specific 'fields' (e.g. Artist name, Song title and Album name, etc.) will not be readily recognized. You would need to write code to identify these and then identify where the values reside.
Good Luck

Manipulate PDF via SQL

what I want to do is automatically create PDFs with data from SQL Server 2008 R2. After creation a string shall be added in the first line of the file. This "header" has to be clear text (right click PDF -> edit -> write string in the first line) and therefore can't be added in the pdf-creation process. The codes in the header are beeing used by another job for further processing.
Is there a way to do that via SQL?
Sample data looks like:
Name | Date | Time | Place | Appointment
John Doe |2014-09-15| 11:00 | Narnia | 12:30
I already found ways to create the PDF, using SSRS and subscription or the procedure mentioned here: http://www.sqlservercentral.com/articles/Miscellaneous/creatingapdffromastoredprocedure/1104/
But I wasn't able to write text to first line, just appended it at the end of the file.
Any help is much appreciated!
This can not be done in SQL. There are a few options that I now of that you can look into to see if it will suite your needs.
NOTE : These are not trivial tasks.
Implement your own device renderer, falling back on the default pdf render.
Override the built in pdf renderer to add your custom header.
Use the SSRS web service api and implement the Render method allowing the access to the Pdf as byte[] and further manipulate it to your needs.
The 3rd method would be the most straightforward and ideal method and would work in both web and windows apps.

Creating a translator/dictionary in IOS

So Im importing a text file that contains a list of character sets. These sets have a meaning they refer to a status of an object. For example TOMTOM100 means Delivery announced. Ones i import he text file the status is presented in 0-5 labels(depends on how many status updates are available).
At first i wanted to do this with a if statement but quickly realized that it would be to much.
if ((trackTraceStatusone.text = #"TOMTOM100"))
{
trackTraceStatusone.text = #"Delivery announced.";
}
Is there a way to create some kind of translator that automatically translates the status in a readable format?
TOMTOM100 > Delivery announced
TOMTOM101 > Delivery Scanned
and so on.
Sounds like a job for NSLocalizedStringFromTable() or the corresponding NSBundle method -localizedStringForKey:value:table:. This will let you load the string from a .strings file in your bundle, which will look something like this:
"TOMTOM100" = "Delivery Announced";
"TOMTOM101" = "Delivery Scanned";
This will also make it easy to provide different strings for different languages. For more information, see the String Resources section of the Resource Programming Guide.

How can I make a perl script that will rename files in a specific directory every couple minutes?

I wanted to add a live picture rotation to my site and i could not find any other way to do it so i decided that i need a cgi script that will:
1. Delete the first picture in the rotation (e.g. pic1.jpg)
2. Rename the rest of the pictures (e.g. rename pic2.jpg to pic1.jpg, pic3.jpg to pic2.jpg, pic4.jpg to pic3.jpg, etc...)
3. Do this every 5 minutes so that the viewers of my site will all be viewing the same picture pretty much at the sime time.
Any help will be much appreciated,
Thanks.
To make this work "so that the viewers of my site will all be viewing the same picture pretty much at the same time", you need to use different urls for each image or make sure you are telling browsers and proxies not to cache the pictures...and not caching is a really bad idea; your viewers will not appreciate it, nor will your server.
Sounds like a pretty bad idea, frankly. File operations are relatively slow, and tends to step on itself in a highly-concurrent application like a webapp.
Look for another way. How about using the current time as a key to choose among pictures?
currentImageIndex = currentTimeRoundedToTheNearestFiveMinutes %
totalNumberOfImages
Edited with more detail on request:
Basically, take the current time, and round it to the nearest five minutes. Doing something like currentHour / 12, using integer math, will give you this; otherwise, truncate the result. Then use the modulo operator (% in Perl, and many languages - handy operator that newcomers tend to overlook) to produce a number from 0 to n-1, where n is the total number of images you're serving. Then you can refer to a mapping table to go from that index to a filename.
Since you say in a comment that you don't need caching, rather than change the filenames of each file, why not have your page point to a file which is a symlink and then change the pointer of the symlink every few minutes. Seems like it would do what you need without the overhead of major file operations.

How do I use IPTC/EXIF metadata to categorise photos?

Many photo viewing and editing applications allow you to examine and change EXIF and IPTC data in JPEG and other image files. For example, I can see things like shutter speed, aperture and orientation in the picture files that come off my Canon A430. There are many, many name/value pairs in all this metadata. But...
What do I do if I want to store some data that doesn't have a build-in field name. Let's say I'm photographing an athletics competition and I want to tag every photo with the competitor's bib number. Can I create a "bib_number" field and assign it a values of "0001", "5478", "8124" etc, and then search for all photos with bib_number="5478"?
I've spent a few hours searching and the best I can come up with is to put this custom information in the "keywords" field but this isn't quite what I'm after. With this socution I'd have to craft a query like "keywords contains bib_number_5478" whereas what I want it "bib_number is 5478".
So do the EXIF and/or IPTC standards allow addtional user-defined field names?
Thanks
Kev
It can be used for that, but it really shouldn't: it's meant to be user-editable and so isn't a safe place to put critical metadata. Using an XMP sidecar is better for this kind of thing: in XMP, any field added that a given app does not understand is, according to the standard, supposed to be ignored by that app and not destroyed.
I don't know if there are applications to do this but by the standards described for JPEG files there is a field called Comments where you can assign values that could act like tags.
C# code:
using System.Windows.Media.Imaging;
using System.IO;
...
FileStream fs = new FileStream(#"<img_path>", FileMode.Open, FileAccess.ReadWrite);
BitmapMetadata bmd = (BitmapMetadata)BitmapFrame.Create(fs).Metadata;
bmd.Comment = "Some Comment Here";
also if you are looking for an application that already has this functionality built into it, then might i recommend Irfan View (open pic, go to Image menu, click on Comments button).
Hope this helps.