|
1 <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|
2 <html lang="en" xml:lang="en"> |
|
3 <head> |
|
4 <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> |
|
5 <meta name="copyright" content="(C) Copyright 2005" /> |
|
6 <meta name="DC.rights.owner" content="(C) Copyright 2005" /> |
|
7 <meta content="concept" name="DC.Type" /> |
|
8 <meta name="DC.Title" content="First steps" /> |
|
9 <meta scheme="URI" name="DC.Relation" content="WRTKit_RSS_Reader_Tutorial-GUID-678d197f-c7b0-4e5e-85e2-f8549c75bbe8.html" /> |
|
10 <meta content="XHTML" name="DC.Format" /> |
|
11 <meta content="GUID-DB42B227-1647-4020-BDB9-DACB26771779" name="DC.Identifier" /> |
|
12 <meta content="en" name="DC.Language" /> |
|
13 <link href="commonltr.css" type="text/css" rel="stylesheet" /> |
|
14 <title> |
|
15 First steps</title> |
|
16 </head> |
|
17 <body id="GUID-DB42B227-1647-4020-BDB9-DACB26771779"><a name="GUID-DB42B227-1647-4020-BDB9-DACB26771779"><!-- --></a> |
|
18 |
|
19 |
|
20 |
|
21 <h1 class="topictitle1"> |
|
22 First steps</h1> |
|
23 |
|
24 <div> |
|
25 |
|
26 <div class="section"><h2 class="sectiontitle"> |
|
27 Preparations</h2> |
|
28 |
|
29 |
|
30 <p> |
|
31 |
|
32 You can find the ready made RSS Reader example in the Examples/RSSReader directory |
|
33 in the WRTKit SDK. In there you can find the by-now familiar widget files: Info.plist |
|
34 for the widget metadata, Icon.png for the S60 application grid icon, and the WRTKit |
|
35 directory for the WRTKit user interface toolkit. You will also find the main HTML |
|
36 file RSSReader.html, a CSS file called RSSReader.css and two JavaScript files |
|
37 RSSReader.js and FeedUpdateBroker.js. As with all WRTKit -based widgets, we will |
|
38 be focusing on the JavaScript files but before we get to those, let's see take a |
|
39 look at the main HTML file: |
|
40 </p> |
|
41 |
|
42 <pre> |
|
43 |
|
44 <?xml version="1.0" encoding="UTF-8"?> |
|
45 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|
46 <html xmlns="http://www.w3.org/1999/xhtml"> |
|
47 <head> |
|
48 <title></title> |
|
49 <script type="text/javascript" src="WRTKit/WRTKit.js"></script> |
|
50 <script type="text/javascript" src="FeedUpdateBroker.js"></script> |
|
51 <script type="text/javascript" src="RSSReader.js"></script> |
|
52 <style type="text/css"> |
|
53 @import url("RSSReader.css"); |
|
54 </style> |
|
55 </head> |
|
56 <body onload="init()"> |
|
57 </body> |
|
58 </html> |
|
59 </pre> |
|
60 |
|
61 <p> |
|
62 |
|
63 You probably immediately noticed that the file is almost identical to the HTML file |
|
64 for the Hello World widget. This is despite that the RSS Reader is much more complex. |
|
65 In fact the only differences are that we are including the two JavaScript files |
|
66 FeedUpdateBroker.js and RSSReader.js instead of HelloWorld.js as in the Hello World |
|
67 widget. That, and the fact that we have a CSS stylesheet file that we also import here, |
|
68 called RSSReader.css. Like for the Hello World widget we have an onload-event handler |
|
69 that calls a function called init() in the JavaScript to allow us to initialize the |
|
70 widget after everything is loaded. |
|
71 </p> |
|
72 |
|
73 <p> |
|
74 |
|
75 You can either examine the ready made files or create your own files as you read the |
|
76 tutorial. The tutorial assumes that you will create your own. If you're doing that then |
|
77 now would be a good time to create a working directory for your own widget, call it |
|
78 RSSReader and copy the WRTKit directory, Info.plist, Icon.png and the FeedUpdateBroker.js |
|
79 file to the your own working directory. The FeedUpdateBroker.js is an AJAX-based RSS |
|
80 fetcher and parser that we will be using in this example. It doesn't really have anything |
|
81 to do with the WRTKit or the user interface for the RSS Reader but we need it in order |
|
82 to be able to fetch and parse RSS feed news items. We will not create it in this tutorial |
|
83 and thus you should just copy it to your own widget working directory. |
|
84 </p> |
|
85 |
|
86 <p> |
|
87 |
|
88 At this point you can also create an empty placeholder for the CSS stylesheet file |
|
89 (RSSReader.css) so that you have the file ready for when we'll create some CSS rules |
|
90 for the widget. Also create an empty placeholder for the RSSReader.js file where the |
|
91 majority of the widget's code will go. We'll return to this in a little bit! |
|
92 </p> |
|
93 |
|
94 </div> |
|
95 |
|
96 <div class="section"><h2 class="sectiontitle"> |
|
97 Architecture</h2> |
|
98 |
|
99 |
|
100 <p> |
|
101 |
|
102 Before we write any code, let's talk about what the architecture of the RSS Reader |
|
103 will be like. As we previously mentioned, the widget will have two views. A main |
|
104 view for showing feed news items and a settings view to allow users to configure |
|
105 what RSS feed to show and how often to update it. We also said that we'll have a |
|
106 custom Options menu. |
|
107 </p> |
|
108 |
|
109 <p> |
|
110 |
|
111 The entire code that implements fetching and parsing RSS feeds will be implemented |
|
112 in the file FeedUpdateBroker.js. The widget code will use it through only one single |
|
113 method: fetchFeed(). The way this works is that we will pass the URL of the RSS |
|
114 feed to the method, as well as a function that will get called when the fetch has |
|
115 been completed. Note that this call is asynchronous - it will immediately return |
|
116 after it's called and the actual outcome of the fetch will not be known until the |
|
117 callback method is called. As an argument to the callback we will receive an object |
|
118 with three properties: status, lastModified and items. The status property will |
|
119 contain a value of either "ok" or "error" depending on the outcome. The lastModified |
|
120 will be present in case the fetch was successful and contains a timestamp that |
|
121 indicates when the RSS feed was last updated. This will allow us to determine whether |
|
122 there is any new news items or not so that we only update the user interface if there |
|
123 really is something to update. Finally the third property "items" contains an array |
|
124 of parsed RSS news items. Each of these is a JavaScript object that has four |
|
125 properties: title for the news item headline, date to indicate when it was created, |
|
126 description for the news item summary, and link with an URL to the full story. |
|
127 </p> |
|
128 |
|
129 <p> |
|
130 |
|
131 We will setup a timer in the widget that will run a function once every second. In |
|
132 this function we will compare the current time to a scheduled "next update" time. |
|
133 If we have reached the next update time, we will use the feed update broker to fetch |
|
134 the RSS news items of the feed that we're interested in. When the feed has been |
|
135 fetched and parsed a callback method will be called and we will react to the callback |
|
136 by either showing an error message (if the update failed), ignoring the callback (if |
|
137 there was no new news items for us), or update the user interface (if there's new |
|
138 news items to show). |
|
139 </p> |
|
140 |
|
141 <p> |
|
142 |
|
143 We also want to be able to update the news items on request and for that we will |
|
144 put an option in the Options menu that triggers a function that sets the next |
|
145 scheduled update time to be immediately. That way the normal update timer will |
|
146 immediately get triggered and cause an update. |
|
147 </p> |
|
148 |
|
149 <p> |
|
150 |
|
151 We will also set the "next update" time whenever the feed update broker is used |
|
152 to fetch new news items. That way we will get an automatic periodic update of the |
|
153 news that will run in the background but can also be triggered to run immediately |
|
154 if the user asks it to be. |
|
155 </p> |
|
156 |
|
157 <p> |
|
158 |
|
159 In order to fetch and update news items with this mechanism we need two things: |
|
160 the URL to the RSS feed and the interval between the automatic updates. These are |
|
161 also the two properties that we will allow the user to configure in the settings |
|
162 view. The properties will be stored in the widget preferences store and updated |
|
163 there whenever the user saves the settings. The settings will be read when the |
|
164 widget starts. |
|
165 </p> |
|
166 |
|
167 <p> |
|
168 |
|
169 When the news items are fetched we will display a notification popup dialog to |
|
170 indicate that the loading is in progress. The main reason why this is important |
|
171 is because the loading takes some time and if we don't react immediately to the |
|
172 user's action then the user will feel like the widget is not responsive. However |
|
173 we don't want to popup a progress dialog every time the widget loads news in the |
|
174 background. That would be really annoying when the user is reading news! This |
|
175 means that we have to know whether the update was triggered manually or if it |
|
176 was scheduled. We'll use a flag to track this and popup the dialog only if the |
|
177 update was commanded by the user. |
|
178 </p> |
|
179 |
|
180 <p> |
|
181 |
|
182 The settings view will contain four controls: a selection control to select the |
|
183 feed URL, another selection control to select the feed update frequency, a save |
|
184 button and a cancel button. |
|
185 </p> |
|
186 |
|
187 <p> |
|
188 |
|
189 The main view in turn will contain a variable amount of controls: one for each |
|
190 news item. The control that we will use is a ContentPanel control, which allows |
|
191 us to collapse and expand the content so that we can display a compact list of |
|
192 news headlines yet allow the user to open up a particular piece of news that |
|
193 is interesting and read the summay or go to the website where the full news |
|
194 story can be found. The news item controls will have the news headline as the |
|
195 caption in the control. Unlike for other controls, ContentPanel captions are |
|
196 interactive and can be clicked. When clicked they will toggle the content area |
|
197 of the panel. We will put the actual news story summary in this content area. |
|
198 The news story summary will be a fragment of HTML that we will construct from |
|
199 each news story. The HTML will also include a link to the website where the |
|
200 full story is located. The HTML will be styled by CSS rules that we will write |
|
201 to the RSSReader.css file. |
|
202 </p> |
|
203 |
|
204 <p> |
|
205 |
|
206 Because we don't know how many news stories we will have at any given time, we |
|
207 will add and remove ContentPanel controls to the main view dynamically whenever |
|
208 there's some update in the RSS feed. But we're environmentally conscious so |
|
209 we'll recycle the ContentPanels. There's no need to throw them away even if they |
|
210 are not needed. So once we have created them we will put them in a pool so that |
|
211 we can recycle them. Later on if we need more ContentPanels will look for them |
|
212 in the pool first and only if there are no ready ContentPanel controls for us |
|
213 will we create more controls (and place them in the pool). Strictly speaking such |
|
214 recycling is not necessary but it doesn't complicate the code much and it's a good |
|
215 skill to know. |
|
216 </p> |
|
217 |
|
218 <p> |
|
219 |
|
220 Finally, as we move between the main view and settings view we will need to |
|
221 change the right softkey so that it's "Exit" in the main view and "Cancel" in |
|
222 the settings view. |
|
223 </p> |
|
224 |
|
225 </div> |
|
226 |
|
227 </div> |
|
228 |
|
229 <div> |
|
230 <div class="familylinks"> |
|
231 <div class="parentlink"><strong>Parent topic:</strong> <a href="WRTKit_RSS_Reader_Tutorial-GUID-678d197f-c7b0-4e5e-85e2-f8549c75bbe8.html">RSS Reader</a></div> |
|
232 </div> |
|
233 </div> |
|
234 |
|
235 </body> |
|
236 </html> |