Mobile App Development Overview
Mobile App Development Overview
• 5. Android architecture
• 6. UI Layouts
• 7. UI Controls / Widgets
• 8. Event handling
GSM
GPRS
EDGE
1G, 2G, 3G, 4G, 5G
IEEE 802.11
Infrared
Bluetooth
Cellular Network
• Base stations transmit to and receive from mobiles at the assigned spectrum
– Multiple base stations use the same spectrum (spectral reuse)
• The service area of each base station is called a cell
• Each mobile terminal is typically served by the ‘closest’
base stations
– Handoff when terminals move
Cellular Network Generations
• Each mobile is assigned a separate frequency channel for the duration of the
call
• Sufficient guard band is required to prevent adjacent channel interference
• Usually, mobile terminals will have one downlink frequency
band and one uplink frequency band
• Different cellular network protocols use different frequencies
• Frequency is a precious and scare resource. We are running
out of it.
frequency
Time Division Multiple Access
15
GSM Evolution to 3G
High Speed Circuit Switched Data
Dedicate up to 4 timeslots for data
connection ~ 50 kbps Good for
real-time applications c.w. GPRS
Inefficient -> ties up resources, even when nothing sent
Not as popular as GPRS (many skipping HSCSD)
Enhanced
GSM Data Rates for
WCDMA
General Packet Radio Services Data rates
up to ~ 115 kbps EDGE
Max: 8 timeslots used as any one time
Packet switched; resources not tied up all the time Contention based.
Efficient, but variable delays GSM / GPRS core network re-used by WCDMA
(3G)
Android
- Android is a mobile operating system (OS) currently developed by Google,
based on the Linux kernel and designed primarily for touchscreen mobile
devices such as smartphones and tablets.
- It was developed by Google, Open Handset Alliance, Android Open Source
Project, Android Inc.
- Source model, open source
- Written in C (core), C++, and Java (UI)
- OS family, Unix
iOS
Windows Mobile
Blackberry
• Web Apps
– They are not real applications; they are really websites that, in
many ways, look and feel like native applications, but are
not implemented as such.
– They are run by a browser and typically written in
HTML5
– Web apps became really popular when HTML5 came around and
people realized that they can obtain native-like functionality in the
browser.
• Hybrid apps
– Hybrid apps are part native apps, part web apps.
– Like native apps, they live in an app store and can take advantage of
the many device features available.
– Like web apps, they rely on HTML being rendered in a
browser, with the caveat that the browser is embedded within
the app.
2. Mobile Devices: Advantages compared to fixed
devices)
• Limited memory
• Limited processing power
• Different technologies and standards
• Limited or awkward input: soft keyboard, phone keypad, touch screen, or
stylus
• Small screens
• Limited and slow network access
• Slow hardware
• Limited battery life
• Limited web browser functionality
• Often inconsistent platforms across devices and etc...
Android Mobile Application Development
Prerequisite
What is Android?
History of Android
• Android applications are usually developed in the Java language using the
Android Software Development Kit
• Once developed, Android applications can be packaged easily and sold out
either through a store such as Google Play, SlideME, Opera Mobile Store,
Mobango, F-droid and the Amazon Appstore.
• Android powers hundreds of millions of mobile devices in more than 190
countries around the world. It's the largest installed base of any mobile
platform and growing fast.
• Every day more than 1 million new Android devices are activated worldwide.
Features Description
Features Description
Multi-tasking User can jump from one task to another and same
time various application can run simultaneously.
Features Description
67
What does it have that other’s don’t?
• MVC2 Architecture
VC2
69
Manufacturer and carrier support
• HTC
• LG
• Sony-Ericsson
• Geeksphone
• Dell
• Motorola
• Acer
• Samsung
• Archos
• Lenovo
• Huawei
70
4. Architecture
Android S/W Stack - Applications
Developers have full access to the same framework APIs used by the
core applications.
• Features
Feature Role
Data Structures
Utilities
File Access
Network Access
Graphics
Android S/W Stack – Runtime (Cont)
Dalvik has been written such that a device can run multiple
VMs efficiently.
Register-based virtual machine
Network Stack
Driver Model
Security
Providing an abstraction layer between the H/W and the rest of the
S/W stack
Android development setup
• Android SDK
Applications
• Google map
5. UI Layouts
• The basic building block for user interface is a View object which is
created from the View class
• It occupies a rectangular area on the screen and is responsible for drawing
and event handling.
• View is the base class for widgets, which are used to create interactive
UI components like buttons, text fields, etc.
..LinearLayout (con…)
• Once the layout has created, it can loaded by the help of application code
• Sample Code
public void onCreate(Bundle savedInstanceState)
{
[Link](savedInstanceState); setContentView([Link].activity_main);
}
Layout Types
• Linear Layout
• Relative Layout
• Table Layout
• Absolute Layout
• Frame Layout
• List View
• Grid View
Linear Layout
• Linear Layout is a view group that aligns all children in either vertically or
horizontally.
Attributes
Attribute Description
Output
Relative Layout
• Relative Layout enables you to specify how child views are positioned
relative to each other.
• The position of each view can be specified as relative to sibling elements
or relative to the parent.
Attributes
By default, all child views are drawn at the top-left of the layout, so you must
define the position of each view using the various layout properties.
Attribute Description
Output
Table Layout
Attributes
Attribute Description
• Input controls are the interactive components in your app's user interface.
• Android provides a wide variety of controls you can use in your UI, such as
buttons, text fields, seek bars, check box, zoom buttons, toggle buttons, and
many more
• RadioButton
• RadioGroup
• • ProgressBar
• Spinner
• TimePicker
TextView Control
Attribute Description
In XML:
<TextView
android:id="@+id/text_id" android:layout_width="300dp"
android:layout_height="200dp" android:capitalize="characters"
android:text="hello_world" android:textColor="@android:color/holo_blue_dark"
android:textColorHighlight="@android:color/primary_text_d ark"
android:layout_centerVertical="true" android:layout_alignParentEnd="true"
android:textSize="50dp"/>
In JAVA:
TextView txtView = (TextView) findViewById([Link].text_id);
Button Control
Attribute Description
In JAVA:
Button b1=(Button)findViewById([Link]);
[Link](new [Link]()
{
@Override
public void onClick(View v)
{
[Link]([Link],"YOUR
MESSAGE",Toast.LENGTH_LONG).show();
}
});
ImageButton Control
Attributes
Attribute Description
In XML:
<ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
android:id="@+id/imageButton" android:layout_centerVertical="true"
android:layout_centerHorizontal="true" android:src="@drawable/abc"/>
In JAVA:
ImageButton imgButton =(ImageButton)
findViewById([Link]);
[Link](new
[Link]()
{
@Override public void onClick(View v)
{
[Link](getApplicationContext(),“Test
Image Button",Toast.LENGTH_LONG).show();
}
});
ToggleButton Control
Attributes
Attribute Description
In XML:
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="On" android:id="@+id/toggleButton1“
android:checked="true" />
<ToggleButton android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Off" android:id="@+id/toggleButton2" android:checked="true“ />
In JAVA:
ToggleButton tg1,tg2;
Button b1;
tg1=(ToggleButton)findViewById([Link]
tton1);
tg2=(ToggleButton)findViewById([Link]
tton2); b1=(Button)findViewById([Link].button2);
[Link](new
[Link]() { @Override public
void onClick(View v) { StringBuffer result =
new StringBuffer();
[Link]("You have clicked first ON Button").append([Link]());
[Link]("\You have clicked Second ON Button
").append([Link]());
[Link]([Link],[Link](),Toast.LENGTH_SHORT)
.show(); } });
AutoCompleteTextView Control
Attributes
Attribute Description
In XML:
<AutoCompleteTextView android:id="@+id/autoCompleteTextView1 "
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView2"
android:layout_below="@+id/textView2"
android:layout_marginTop="54dp" android:ems="10" />
In JAVA:
AutoCompleteTextView autocompletetextview; String[] arr = { "Paries,France",
"PA,United States","Parana,Brazil", "Padua,Italy", "Pasadena,CA,United
States"};
autocomplete = (AutoCompleteTextView) findViewById([Link].autoCompleteTextView1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,[Link].select_dialog_item, arr);
[Link](2); [Link](adapter);
Output
CheckBox Control
Attribute Description
In XML:
<CheckBox android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Do you like
android“
android:checked="false“
/>
<CheckBox android:id="@+id/checkBox2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Do you like android "
android:checked="false“ />
In JAVA:
);
CheckBox ch1,ch2; Button b1,b2;
ch1=(CheckBox)findViewById([Link].checkBox1);
ById([Link].checkBox2); b1=(Button)findViewById([Link]);
[Link](new [Link]() {
@Override
public void onClick(View v) { StringBuffer
result = new StringBuffer();
[Link]("Thanks : ").append([Link]()); [Link]("\nThanks:
").append([Link]()); [Link]([Link],
[Link](), Toast.LENGTH_LONG).show(); }
RadioButton Control
In XML:
<RadioGroup
<RadioButton
android:text="JAVA"
android:id="@+id/radioButton1"
android:checked="false“ />
<RadioButton
android:text="ANDROID" android:id="@+id/radioButton2“
android:checked="false“ />
Example (con…)
In JAVA:
RadioButton rb1; RadioGroup rg1; Button
b1;
addListenerRadioButton();
private void addListenerRadioButton() {
rg1 = (RadioGroup) findViewById([Link]);
b1 = (Button) findViewById([Link].button1);
[Link](new [Link]() { @Override
public void onClick(View v) {
int selected=[Link]();
rb1=(RadioButton)findViewById(selected);
[Link]([Link],[Link](),[Link] NGTH_LONG).show(); }
}); }
RadioGroup Control
(Refer RadioButton)
Spinner Control
TimePicker Control
• Time Picker allows you to select the time of day in either 24 hour or
AM/PM mode.
• The time consists of hours, minutes and clock format.
• Android provides this functionality through TimePicker
class.
7. Event Handling
• Events are a useful way to collect data about a user's interaction with interactive
components of Applications.
• Like button presses or screen touch etc.
• The Android framework maintains an event queue as first-in, first-out (FIFO)
basis.
• Capture these events in program and take appropriate action as per
requirements.
• Event Management
– Event Listeners
• An event listener is an interface in the View class that contains a single
callback method.
• These methods will be called by the Android framework when the View to
which the listener has been registered is triggered by user interaction with
the item in the UI.
– Event Handlers
• When an event happens and we have registered in the event listener for the
event, the event listener calls the Event Handlers, which is the method that
actually handles the event.
Example
• In JAVA
public void Font_Change(View v) { TextView txtView = (TextView)
findViewById([Link]);
[Link](25);
}
8. Tools - Eclipse IDE
Eclipse IDE (con…)
DDMS Configuration
New Android Project Creation
Giving Name Application /
Project
Con…
Icon Customization
Customized Icon
Activity type selection
Customize the activity name
Default code appear in Eclipse IDE
Creating AVD Manager
AVD Configuration
Launching the AVD
Launching the AVD (con…)
AVD – Emulator
Configure the Logcat
Application running status displayed in Logcat
Output
9. Application Structure
src
• bin
– This folder contains the Androidpackage
files .apk built by the ADT during the build process and
everything else needed to run an Android application.
• res/drawable-hdpi
– This is a directory for drawable objects that are designed for high-
density screens.
• res/layout
– This is a directory for files that define your app's user interface.
• res/values
– This is a directory for other various XML files that contain a collection
of resources, such as strings and colours definitions.
• [Link]
– This is the manifest file which describes the fundamental
characteristics of the app and defines each of its components.
AndroidManifest
Practices
UNIT 2
Introduction to Activity and Intents- Understanding Activity Life Cycle - Linking Activities -
Passing Data – Toast - Displaying Dialog Window – Notifications – Services - Broadcast
Receiver- Content Provider - SQLite Database - Publish App in Play store- Sample
Applications
Android Application Components
Application components are the basic building blocks of an application and these components
will act as an entry point to allow system or user to access our app. Basic core application
components that can be used in Android application.
❖ Activities
❖ Intents
❖ Content Providers
❖ Broadcast Receivers
❖ Services.
Android Components.
❖ Activities
❖ Intents
❖ Content Providers
❖ Broadcast Receivers
❖ Services
1. Activity
2. Services
}
3. A Content provider is implemented as a subclass of ComtentProvider class and must
implement a standard set of APIs that enable other applications to perform
transactions.
Introduction to Activity:
…….
</activity>
…….
</application>
</manifest>
Android system initiates its program with in an Activity starting with a call
on onCreate() callback method. There is a sequence of callback methods that start up an
activity and a sequence of callback methods that tear down an activity.
Figure 2.1 Activity Sequence
Activity State
[Link]’t exist State
2. Foreground State
3. Background State
[Link] State
1. Running State
An activity is in the running state if it’s shown in the foreground of the users’ screen. Activity
is in the running state when the user is interacting with it.
2. Paused State
When an activity is not in the focus but is still alive for the user, it’s in a paused state. The
activity comes in this state when some other activity comes in with a higher position in the
window.
3. Resumed State
It is when an activity goes from the paused state to the foreground that is an active state.
4. Stopped State
When an activity is no longer in the activity stack and not visible to the users.
Android Activity. Methods. Android activities go through four states during their entire
lifecycle. These activities have callback methods() to describe each activity in each of the
four stages. These methods need to be overridden by the implementing subclass. In Android,
we have the following 7 callback methods that activity uses to go through the four states:
1. onCreate()
2. onStart()
3. onPause()
4. onRestart()
5. onResume()
6. onStop()
7. onDestroy()
1. onCreate()
The Android oncreate() method is called at the very start when an activity is created. An
activity is created as soon as an application is opened. This method is used in order to create
an Activity.
The Android onstart() method is invoked as soon as the activity becomes visible to the users.
This method is to start an activity. The activity comes on the forescreen of the users when this
method is invoked.
Syntax:
@Override protected void onStart()
{
[Link]();
...
}
3. onPause()
The Android onPause() method is invoked when the activity doesn’t receive any user input
and goes on hold. In the pause state, the activity is partially visible to the user. This is done
when the user presses the back or home buttons. Once an activity is in the pause state, it can
be followed by either onResume() or onStopped() callback method.
Syntax:
@Override protected void onPause()
{
[Link]();
...
}
4. onRestart()
The Android onRestart() method is invoked when activity is about to start from the stop state.
This method is to restart an activity that had been active some time back. When an activity
restarts, it starts working from where it was paused.
Syntax:
@Override protected void onRestart()
{
[Link]();
...
}
5. onResume()
The Android onResume() method is invoked when the user starts interacting with the user.
This callback method is followed by onPause(). Most of the functionalities of an application
are implemented using onResume().
Syntax:
@Override protected void onResume()
{
[Link]();
...
}
6. onStop()
The Android onStop() method is invoked when the activity is no longer visible to the user.
The reason for this state is either activity is getting destroyed or another existing activity
comes back to resume state.
Syntax:
@Override protected void onStop()
{
[Link]();
...
}
7. onDestroy()
The Android onDestroy() is the method that is called when an activity finishes and the user
stops using it. It is the final callback method received by activity, as after this it is destroyed.
Syntax:
@Override protected void onDestroy()
{
[Link]();
...
}
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
Log.d("lifecycle","onCreate invoked");
}
@Override
protected void onStart() {
[Link]();
Log.d("lifecycle","onStart invoked");
}
@Override
protected void onResume() {
[Link]();
Log.d("lifecycle","onResume invoked");
}
@Override
protected void onPause() {
[Link]();
Log.d("lifecycle","onPause invoked");
}
@Override
protected void onStop() {
[Link]();
Log.d("lifecycle","onStop invoked");
}
@Override
protected void onRestart() {
[Link]();
Log.d("lifecycle","onRestart invoked");
}
@Override
protected void onDestroy() {
[Link]();
Log.d("lifecycle","onDestroy invoked");
}
}
activity_main.xml
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</[Link]>
Introduction to Intents:
Android Intent is the message that is passed between components such as activities, content
providers, broadcast receivers, services [Link] is generally used with startActivity() method to
invoke activity, broadcast receivers etc.
1. Explicit Intents
2. Implicit Intents
1) Implicit Intent
Implicit Intent doesn't specifiy the component. In such case, intent provides information of
available components provided by the system that is to be invoked
Example:
2) Explicit Intent
Explicit Intent specifies the component. In such case, intent provides the external class to
be invoked.
Intent i = new Intent(getApplicationContext(), [Link]);
startActivity(i);
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="60dp"
android:ems="10"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.575"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_marginLeft="156dp"
android:layout_marginTop="172dp"
android:text="Visit"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
</[Link]>
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class MainActivity extends AppCompatActivity {
Button button;
EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
button = findViewById([Link]);
editText = findViewById([Link]);
[Link](new [Link]() {
@Override
public void onClick(View view) {
String url=[Link]().toString();
Intent intent=new Intent(Intent.ACTION_VIEW, [Link](url));
startActivity(intent);
}
});
}
}
Linking Activity:
⮚ To start an Activity
An Activity represents a single screen in an [Link] a new instance of an Activity by
passing an Intent to startActivity()
⮚ To start a Service
A Service is a component that performs operations in the background and does not
have a user interface. You can start a service to perform a one-time operation(such as
downloading a file) by passing an Intent to startService()
⮚ To deliver a Broadcast
A broadcast is a message that any app can receive. The system delivers various
broadcasts for system events, such as when the system boots up or the device starts
charging. You can deliver a broadcast to other apps by passing an Intent to
sendBroadcast() or sendOrderedBroadcast().
Example:
public class MainActivity extends Activity implements OnClickListener {
Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState); setContentView([Link].activity_main);
btn = (Button) findViewById([Link]);
[Link](this);
}
@Override
public void onClick(View view) { Intent intent = new
Intent(getApplicationContext(), [Link]);
[Link]("message", "Hello From Main Activity” );
startActivity(intent);}}
public class SecondActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_another);
Intent intent = getIntent();
String msg = [Link]("message"); Toast toast = [Link](this,
msg,Toast . LENGTH_ LONG);
[Link]();
}
}
Toasts:
• A toast provides simple feedback about an operation in a small popup. It only fills the
amount of space required for the message and the current activity remains visible and
interactive,Toasts automatically disappear after a timeout.
• First, instantiate a Toast object with one of the makeText() methods.
• This method takes three parameters: the application Context, the text message, and
the duration for the toast. It returns a properly initialized Toast object.
• You can display the toast notification with show()
• Context context = getApplicationContext(); CharSequence text = "Hello toast!";
(or)
(or)
[Link](getApplicationContext(),”Hello toast!”,
Toast.LENGTH_“SHORT).show();
Notification
• A notification is a message you can display to the user outside of your application's
normal UI.
• When you tell the system to issue a notification, itfirst
appears as an icon in the notification area.
• To see the details of the notification, the user opens
the notification drawer.
• Both the notification area and the notification drawer are system-controlled areas that
the user can view at any time.
Android Toast class provides a handy way to show users alerts but problem is that these
alerts are not persistent which means alert flashes on the screen for a few seconds and then
disappears.
Step 1 - Create Notification Builder
• A first step is to create a notification builder using
[Link]().
• Use Notification Builder to set various Notification properties like its small and large
icons, title, priority etc.
• Syntax
[Link] mBuilder = new [Link](this);
Services:
• A service is a component that runs in the background to perform long-running
operations without needing to interact with the user and it works even if application
is destroyed.
• A service can essentially take two states
– Started
• A service is started when an application component, such as an
activity, starts it by calling startService().
• Once started, a service can run in the background indefinitely, even if
the component that started it is destroyed.
• Android Services are the application components that run in the background. Service
is process that doesn’t need any direct user interaction.
• As they perform long-running processes without user intervention, they have no User
Interface.
• They can be connected to other components and do inter-process communication
(IPC).
Figure 2.4 Android Services
1. Foreground Services
Foreground services are those services that are visible to the users. The users can interact
with them at ease and track what’s happening. These services continue to run even when
users are using other applications.
2. Background Services
These services run in the background, such that the user can’t see or access them. These are
the tasks that don’t need the user to know them
3. Bound Services
Bound service runs as long as some other application component is bound to it. Many
components can bind to one service at a time, but once they all unbind, the service will
destroy.
Bound
[Link]()
2. bindService()
3. serviceConnection()
4. onstartCommand()
5. onService Connected()
Android services life-cycle can have two forms of services and they follow two paths, that
are:
• Started Service
• Bounded Service
1. Started Service
2. Bound Service
IntentService()
• There’s an additional service class, that extends Service class, IntentService Class. It
is a base class for services to handle asynchronous requests.
• It enables running an operation on a single background. It executes long-running
programs without affecting any user’s interface interaction.
• Intent services run and execute in the background and terminate themself as soon as
they are executed completely.
• The service base class defines certain callback methods to perform operations on
applications. When we talk about Android services it becomes quite obvious that
these services will do some operations and they’ll be used. The following are a few
important methods of Android services :
1. onStartCommand()
2. onBind()
3. onCreate()
4. onUnbind()
5. onDestroy()
6. onRebind()
1. onStartCommand()
The system calls this method whenever a component, say an activity requests ‘start’ to a
service, using startService().Once we use this method it’s our duty to stop the service
using stopService() or stopSelf().
2. onBind()
3. onUnbind()
The system invokes this when all the clients disconnect from the interface published by
the service.
4. onRebind()
The system calls this method when new clients connect to the service. The system calls it
after the onBind() method.
5. onCreate()
This is the first callback method that the system calls when a new component starts the
service. We need this method for a one-time set-up.
6. onDestroy()
This method is the final clean up call for the system. The system invokes it just before the
service destroys. It cleans up resources like threads, receivers, registered listeners, etc.
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/** Called when The service is no longer used and is being destroyed */
@Override
public void onDestroy() {
}
}
Broadcast Receivers
Broadcast Receivers simply respond to broadcast messages from other applications or from
the system itself. These messages are sometime called events or intents. For example,
applications can also initiate broadcasts to let other applications know that some data has
been downloaded to the device and is available for them to use, so this is broadcast receiver
who will intercept this communication and will initiate appropriate action.
Here are following two important steps to make BroadcastReceiver works for the system
broadcasted intents −
Creating the Broadcast Receiver.
Registering Broadcast Receiver
There is one additional steps in case you are going to implement your custom intents then
you will have to create and broadcast those intents.
Creating the Broadcast Receiver
A broadcast receiver is implemented as a subclass of BroadcastReceiver class and
overriding the onReceive() method where each message is received as a Intent object
parameter.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
[Link](context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
Broadcast-Receiver
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="[Link].BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>
</application>
Now whenever your Android device gets booted, it will be intercepted by
BroadcastReceiver MyReceiver and implemented logic inside onReceive() will be executed.
There are several system generated events defined as final static fields in the Intent class.
The following table lists a few important system events.
[Link].BATTERY_CHANGED
1
Sticky broadcast containing the charging state, level, and other information about the
battery.
[Link].BATTERY_LOW
2
Indicates low battery condition on the device.
[Link].BATTERY_OKAY
3
Indicates the battery is now okay after being low.
[Link].BOOT_COMPLETED
4
This is broadcast once, after the system has finished booting.
[Link].BUG_REPORT
5
Show activity for reporting a bug.
[Link]
6
Perform a call to someone specified by the data.
[Link].CALL_BUTTON
7 The user pressed the "call" button to go to the dialer or other appropriate UI for
placing a call.
[Link].DATE_CHANGED
8
The date has changed.
[Link]
9
Have the device reboot.
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="[Link].CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
Example: [Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/**
* Created by TutorialsPoint7 on 8/23/2016.
*/
public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
[Link](context, "Intent Detected.", Toast.LENGTH_LONG).show();
}
}
[Link]
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="[Link]" />
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="[Link].CUSTOM_INTENT">
</action>
</intent-filter>
</receiver>
</application>
</manifest>
res/layout/activity_main.xml
<RelativeLayout
xmlns:android="[Link]
xmlns:tools="[Link]
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example of Broadcast"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:textSize="30dp" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tutorials point "
android:textColor="#ff87ff09"
android:textSize="30dp"
android:layout_above="@+id/imageButton"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageButton"
android:src="@drawable/abc"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button2"
android:text="Broadcast Intent"
android:onClick="broadcastIntent"
android:layout_below="@+id/imageButton"
android:layout_centerHorizontal="true" />
</RelativeLayout>
Content Provider:
A content provider component supplies data from one application to others on request. Such
requests are handled by the methods of the ContentResolver class. A content provider can use
different ways to store its data and the data can be stored in a database, in files, or even over a
network.
content:// – Mandatory part of the URI as it represents that the given URI is a Content
URI.
authority – Signifies the name of the content provider like contacts, browser, etc. This
part must be unique for every content provider.
optionalPath – Specifies the type of data provided by the content provider. It is essential
as this part helps content providers to support different types of data that are not related
to each other like audio and video files.
optionalID – It is a numeric value that is used when there is a need to access a particular
record.
Following are the six abstract methods and their description which are essential to override as
the part of ContenProvider class:
<string name="app_name">Content_Provider_In_Android</string>
</resources>.
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
static {
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch ([Link](uri)) {
case uriCode:
count = [Link](TABLE_NAME, values, selection,
selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch ([Link](uri)) {
case uriCode:
count = [Link](TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
// creating a database
private static class DatabaseHelper extends SQLiteOpenHelper {
// defining a constructor
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
[Link](CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical"
app:layout_constraintBottom_toTopOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.13"
tools:ignore="MissingConstraints">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:layout_marginBottom="70dp"
android:fontFamily="@font/roboto"
android:text="@string/heading"
android:textAlignment="center"
android:textAppearance="@style/[Link]"
android:textColor="@android:color/holo_green_dark"
android:textSize="36sp"
android:textStyle="bold" />
<EditText
android:id="@+id/textName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="40dp"
android:fontFamily="@font/roboto"
android:hint="@string/hintText" />
<Button
android:id="@+id/insertButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickAddDetails"
android:text="@string/insertButtontext"
android:textAlignment="center"
android:textAppearance="@style/[Link].Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<Button
android:id="@+id/loadButton"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:layout_marginBottom="20dp"
android:background="#4CAF50"
android:fontFamily="@font/roboto"
android:onClick="onClickShowDetails"
android:text="@string/loadButtonText"
android:textAlignment="center"
android:textAppearance="@style/[Link].Display1"
android:textColor="#FFFFFF"
android:textStyle="bold" />
<TextView
android:id="@+id/res"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20dp"
android:clickable="false"
android:ems="10"
android:fontFamily="@font/roboto"
android:textColor="@android:color/holo_green_dark"
android:textSize="18sp"
android:textStyle="bold" />
</LinearLayout>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:srcCompat="@drawable/banner" />
</[Link]>
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Override
[Link](savedInstanceState);
setContentView([Link].activity_main);
}
@Override
InputMethodManager imm =
(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
[Link](getCurrentFocus().getWindowToken(),
0);
return true;
[Link]([Link], ((EditText)
findViewById([Link])).getText().toString());
getContentResolver().insert(MyContentProvider.CONTENT_URI,
values);
}
public void onClickShowDetails(View view) {
// content URI
Cursor cursor =
getContentResolver().query([Link]("content://[Link]/users"), null, null,
null, null);
if([Link]()) {
while (![Link]()) {
[Link]("\n"+[Link]([Link]("id"))+ "-"+
[Link]([Link]("name")));
[Link]();
[Link](strBuild);
else {
<manifest xmlns:android="[Link]
package="[Link].content_provider_in_android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="[Link]
r"
android:authorities="[Link]"
android:enabled="true"
android:exported="true"></provider>
<activity android:name=".MainActivity">
<intent-filter>
<category
android:name="[Link]" />
</intent-filter>
</activity>
<meta-data
android:name="preloaded_fonts"
android:resource="@array/preloaded_fonts" />
</application>
</manifest>
SQLite Database:
What is SQLite?
SQLite is an in-process library that implements a self-contained, serverless, zero-
configuration, transactional SQL database engine. It is a database, which is zero-configured,
which means like other databases you do not need to configure it in your system.
SQLite engine is not a standalone process like other databases, you can link it statically or
dynamically as per your requirement with your application. SQLite accesses its storage files
directly.
Why SQLite?
SQLite does not require a separate server process or system to operate (serverless).
SQLite comes with zero-configuration, which means no setup or administration
needed.
A complete SQLite database is stored in a single cross-platform disk file.
SQLite is very small and light weight, less than 400KiB fully configured or less than
250KiB with optional features omitted.
SQLite is self-contained, which means no external dependencies.
SQLite transactions are fully ACID-compliant, allowing safe access from multiple
processes or threads.
SQLite supports most of the query language features found in SQL92 (SQL2)
standard.
SQLite is written in ANSI-C and provides simple and easy-to-use API.
SQLite is available on UNIX (Linux, Mac OS-X, Android, iOS) and Windows
(Win32, WinCE, WinRT).
SQLite Commands
The standard SQLite commands to interact with relational databases are similar to SQL.
They are CREATE, SELECT, INSERT, UPDATE, DELETE and DROP. These commands
can be classified into groups based on their operational nature
SQLiteOpenHelper class
There are many methods in SQLiteOpenHelper class. Some of them are as follows:
SQLiteDatabase class
It contains methods to be performed on sqlite database such as create, update, delete, select
etc.
There are many methods in SQLiteDatabase class. Some of them are as follows:
Example:
[Link]
package [Link];
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
// Creating Tables
@Override
public void onCreate(SQLiteDatabase db) {
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACS
+ "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT,"
+ KEY_PH_NO + " TEXT" + ")";
[Link](CREATE_CONTACTS_TABLE);
}
// Upgrading database
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
[Link]("DROP TABLE IF EXISTS " + TABLE_CONTACTS);
// Create tables again
onCreate(db);
}
// Inserting Row
[Link](TABLE_CONTACTS, null, values);
//2nd argument is String containing nullColumnHack
[Link](); // Closing database connection
}
SQLiteDatabase db = [Link]();
Cursor cursor = [Link](selectQuery, null);
// looping through all rows and adding to list
if ([Link]()) {
do {
Contact contact = new Contact();
[Link]([Link]([Link](0)));
[Link]([Link](1));
[Link]([Link](2));
// Adding contact to list
[Link](contact);
} while ([Link]());
}
// updating row
return [Link](TABLE_CONTACTS, values, KEY_ID + " = ?",
new String[] { [Link]([Link]()) });
}
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Override
protected void onCreate(Bundle savedInstanceState) {
[Link](savedInstanceState);
setContentView([Link].activity_main);
DatabaseHandler db = new DatabaseHandler(this);
// Inserting Contacts
Log.d("Insert: ", "Inserting ..");
[Link](new Contact("Ravi", "9100000000"));
[Link](new Contact("Srinivas", "9199999999"));
[Link](new Contact("Tommy", "9522222222"));
[Link](new Contact("Karthik", "9533333333"));
Unit – III
Introduction to Objective-C - Data Types andExpressions - Decision Making and Looping -
Objects and Classes – Property – Messaging – Category - Extensions - Fast Enumeration - NSArray
and NSDictionary - Methods and Selectors - Static and DynamicObjects - Exception Handling -
Memory Management - RequiredTools–Xcode, iOS Simulator, Instruments,ARC and Frameworks
1
Introduction
• Objective-C is a general-purpose, object-oriented programming language that adds
Smalltalk-style messagingtotheCprogramminglanguage.
• This is the main programming language used by Apple for the OS X and iOS operating
systemsand theirrespectiveAPIs,CocoaandCocoaTouch.
• Initially, Objective-C was developed by NeXT for its NeXTSTEP OS from whom it was
takenoverby AppleforitsiOS andMacOS X.
Objective-C Program Structure
• Preprocessor Commands
• Interface
• Implementation
• Method
• Variables
• Statements &Expressions
• Comments
Example
#import <Foundation/Foundation.h> @interface SampleClass:NSObject
- (void)sampleMethod; @end
@implementation SampleClass
- (void)sampleMethod
{
NSLog(@"Hello,World!\n");
}
@end
int main(){
/*myfirstprograminObjective-C*/
SampleClass *sampleClass = [[SampleClass alloc]init];
[sampleClass sampleMethod];
return 0;
2
}
Token
An Objective-C program consists of various tokens and a token is either,
– a keyword
– an identifier
– a constant
– a string literal, or a symbol.
The semicolon is a statement terminator.
NSLog(@"Hello,World!\n");
(or)
NSLog (
@
3
"Hello, World!\n"
)
;
• Floating-Point Types
4
– float - 4byte
– double - 8byte
– long double - 10 byte
• The void Type
– Function returns asvoid
– Function arguments asvoid
Variables
• A variable is nothing but a name given to a storage area that our programs can
manipulate.
• Each variable in Objective-C has a specific type, which determines the size and layout
of the variable's memory,
– the range of values that can be stored within that memory
– the set of operations that can be applied to the variable.
•
Basic variabletypes
• char
– Typically a single octet (one byte). This is an integer type.
• int
– The most natural size of integer for the machine.
• float
– A single-precision floating point value.
• double
– A double-precision floating point value.
• void
– Represents the absence of type.
Example
#import <Foundation/Foundation.h>
// variable declaration
extern int a, b;
5
extern int c;
extern float f;
int main (){
/*
variable
definitio
n:*/ inta,
b; int c;
floatf;
/* actual
initializat
ion */ a =
10; b = 20;
c=a+b;
NSLog(@"value of c : %d \n",
c); f =70.0/3.0;
NSLog(@"value of f : %f
\n",f); return 0;
}
Constants
• The constants refer to fixed values that the program may not alter during its execution.
• Constants can be of any of the basic data types like
– integer constant
– floating constant
– character constant
– string literal
– enumeration constant
Operators
• Arithmetic Operators
• Relational Operators
• Logical Operators
6
• Bitwise Operators
• Assignment Operators
• Misc Operators
– sizeof()
– & operator
– * operator
– ?: operator
Decision Making - Branching
Decision making structures require that the programmer specify one or more conditions
to be evaluated or tested by the program, along with a statement or statements to be executed if
the condition is determined to be true, and optionally, other statements to be executed if the
condition is determined to be false as shown in figure 3.1.
7
/* statement(s) will execute if the boolean expression is false */
}
• Nested if statement
if( boolean_expression 1) {
/* Executes when the boolean expression 1 is true */
if(boolean_expression 2) {
/* Executes when the boolean expression 2 is true */
}}
• Switch statement
switch(expression)
{
case constant-expression:
statement; break;
/* you can have any number of case statements */ default :
/* optional */
statement(s); break;
}
Decision making - Looping
A looping statement allows us to execute a statement or group of statements multiple
times. It’s flowchart is shown in figure 3.2.
8
Figure 3.2 Decision making – Looping flowchart
Looping statement
• While loop
while(condition) {
statement(s); }
• Do while loop
do {
statement(s);
}while( condition );
• For loop
for (init; condition; increment/decrement) {
statement(s); }
Classes & Objects
• The main purpose of Objective-C programming language is to add object orientation
to the C programming language.
• Classes are the central feature of Objective-C that support object-oriented programming
and are often called user-defined types.
• A class is used to specify the form of an object and it combines data representation and
methods for manipulating that data into one neat package.
• The data and methods within a class are called members of the class.
Objective-C characteristics
• The class is defined in two different sections namely @interface and @implementation.
• Almost everything is in form of objects.
• Objects receive messages and objects are often referred as receivers.
• Objects contain instance variables.
• Objects and instance variables have scope.
• Classes hide an object's implementation.
• Properties are used to provide access to class instance variables in other classes.
Class Definitions
• Define a blueprint for a data type.
9
– Define what the class name means?
– What an object of the class will consist?
– What operations can be performed on such an object?
• A class definition starts with the keyword @interface followed by the
interface(class) name;
and the class body, enclosed by a pair of curly braces.
• In Objective-C, all classes are derived from the base class called NSObject.
It is the super class of all Objective-C classes. It provides basic methods like
memory allocation and initialization.
Example
@interface Box:NSObject {
//Instance variables
double length; // Length of a box
double breadth; // Breadth of a box
}
// Property
@property(nonatomic, readwrite) double height;
@end
Example
Box box1 = [[Box alloc]init]; // Create box1 object of type Box
Box box2 = [[Box alloc]init]; // Create box2 object of type Box
10
• The properties of objects of a class can be accessed using the direct member
access operator (.)
Example
#import<Foundation/Foundation.h>
@interface Box:NSObject {
double length;
double breadth;
double height;
}
@property(nonatomic, readwrite) double height;
-(double) volume;
@end
@implementation Box
@synthesize height;
-(id)init
{
self = [super init];
length = 1.0;
breadth = 1.0;
return self;
}
-(double) volume
{ return length*breadth*height;
}
@end
int main( )
{
Box *box1 = [[Box alloc]init];
Box *box2 = [[Box alloc]init];
double volume = 0.0;
[Link] = 5.0;
11
[Link] = 10.0;
volume = [box1 volume];
NSLog(@"Volume of Box1 : %f", volume);
volume = [box2 volume];
NSLog(@"Volume of Box2 : %f", volume); return 0; }
Function
• A function is a group of statements that together perform a task.
• A function declaration tells the compiler about a function's name, return type, and
parameters.
• A function definition provides the actual body of the function.
• Call the function as method
Defining a Method
Syntax:
- (return_type) method_name:( argumentType1
)argumentName1 joiningArgument2:(argumentType2)argumentName2
joiningArgumentN:( argumentTypeN )argumentNameN
{
body of the function
}
Example
/* function returning the max between two numbers */
- (int) max:(int) num1 Num2:(int) num2
{
int result;
if (num1 > num2)
{
result = num1;
}else{
result=num2;
}
12
return result;}
Method Declaration
Syntax:
- (return_type) function_name:( argumentType1)argumentName1 joiningArgument2:
( argumentType2 )argumentName2 ... joiningArgumentN:( argumentTypeN
)argumentNameN;
Example
-(int) max:(int)num1 andNum2:(int)num2;
Example
#import<Foundation/Foundation.h>
@interface SampleClass:NSObject
/* method declaration */
- (int)max:(int)num1 andNum2:(int)num2;
@end
@implementation SampleClass
/* method returning the max between two numbers */
- (int)max:(int)num1 andNum2:(int)num2{
/* local variable declaration
*/ int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
@end
int main ()
{
/* local variable definition */
int a = 100;
13
int b = 200;
int ret;
SampleClass *sampleClass = [[SampleClass alloc]init];
/* calling a method to get max value */
ret = [sampleClass max:a andNum2:b];
NSLog(@"Max value is : %d\n", ret );
return 0;
}
Log Handling
NSLog method
– To print logs, we use the NSLog method
– Syntax:
N“Log(@”“tring”);
– Example
#import<Foundation/Foundation.h>
int main() {
NSLog(@"Hello,
World! \n");
return 0;
}
Example
• DebugLog Method
– To print logs in a live build.
#import <Foundation/Foundation.h>
#if DEBUG == 0
#define DebugLog(...)
#elif DEBUG== 1
#define DebugLog(...) NSLog(VA_ARGS)
#endif
int main() {
14
DebugLog(@"Debug log, our custom addition gets \ printed during debug
only" );
NSLog(@"NSLog gets printed always" );
return 0;
}
Output
• We compile and run the program in debug mode, the output is,
– Debug log, our custom addition gets printed during debug
only
– NSLog gets printed always
• We compile and run the program in release mode, the output is,
– NSLog gets printed always
Property
• To ensure that the instance variable of the class can be accessed outside the class.
• The various parts are the property declaration are as follows
– Properties begin with @property, which is a keyword
– Access specifiers (atomic, nonatomic, readwrite, readonly, strong, weak )
– This is followed by the data-type of the variable.
– Finally, we have the property name terminated by a semicolon.
– We can add synthesize statement in the implementation class.
• Properties let other objects inspect or change its state
• A well-designed object-oriented program, it’s not possible to directly access the
internal state of an object as shown in figure 3.3
15
Figure 3.3 Setter and Getter methods
Messaging
• In Objective-C, messages aren’t bound to method implementations until runtime.
• The compiler converts a message expression,
[receiver message] into a call on a messaging function, objc_msgSend.
• This function takes the receiver and the name of the method mentioned in the
message—that is, the method selector—as its two principal parameters:
objc_msgSend(receiver, selector)
• Any arguments passed in the message are also handed to objc_msgSend:
objc_msgSend(receiver, selector, arg1, arg2, ...)
• The messaging function does everything necessary for dynamic binding:
– It first finds the procedure (method implementation) that the selector refers to.
Since the same method can be implemented differently by separate classes, the
precise procedure that it finds depends on the class of the receiver.
– It then calls the procedure, passing it the receiving object (a pointer to its data),
along with any arguments that were specified for the method.
– Finally, it passes on the return value of the procedure as its own return value.
Messaging Framework
16
Figure 3.4 Messaging framework
• When a message is sent to an object, the messaging function follows the object’s is a
pointer to the class structure where it looks up the method selector in the dispatch table.
• If it can’t find the selector here, objc_msgSend follows the pointer to the superclass
and tries to find the selector in its dispatch table.
• Successive failures cause objc_msgSend to climb the class hierarchy until it reaches
the NSObject class as indicated in figure 3.4.
• Once it locates the selector, the function calls the method entered in the table and passes
it the receiving object’s data structure.
• To speed the messaging process, the runtime system caches the selectors and addresses
of methods as they are used.
• There’s a separate cache for each class, and it can contain selectors for inherited
methods as well as for methods defined in the class.
• Before searching the dispatch tables, the messaging routine first checks the cache of
the receiving object’s class.
• If the method selector is in the cache, messaging is only slightly slower than a function
call.
• Caches grow dynamically to accommodate new messages as the program runs.
Categories
17
• To extend an existing class by adding behavior that is useful only in certain situations.
• If you need to add a method to an existing class, the easiest way is to use a category.
• To declare a category uses the @interface keyword.
Syntax
@interface ClassName (CategoryName)
@end
Characteristics of category
• A category can be declared for any class, even if you don't have the original
implementation source code.
• Any methods that you declare in a category will be available to all instances of the
original class, as well as any subclasses of the original class.
• At runtime, there's no difference between a method added by a category and one that
is implemented by the original class.
Person.h
@interface Person : NSObject
@property (readonly) NSMutableArray* friends;
@property (copy) NSString* name;
- (void)sayHello;
- (void)sayGoodbye;
@end
Person.m
#import "Person.h"
@implementation Person
@synthesize name = _name;
@synthesize friends = _friends;
-(id)init
{
self = [super init];
if(self)
18
{
_friends = [[NSMutableArray alloc] init];
}
return self;
}
- (void)sayHello
{
NSLog(@"Hello, says %@.", _name);
}
- (void)sayGoodbye
{
NSLog(@"Goodbye, says %@.", _name);
}
@end
Person+Relations.h
#import<Foundation/Foundation.h>
#import "Person.h"
@interface Person (Relations)
- (void)addFriend:(Person *)aFriend;
- (void)removeFriend:(Person *)aFriend;
- (void)sayHelloToFriends;
@end
Person+Relations.m
#import"Person+Relations.h"
@implementation Person (Relations)
- (void)addFriend:(Person *)aFriend
{
[[self friends] addObject:aFriend];
}
19
- (void)removeFriend:(Person *)aFriend
{
Main.m
#import <Foundation/Foundation.h>
#import "Person.h"
#import "Person+Relations.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
Person *joe = [[Person alloc] init];
[Link] = @"Joe";
Person *bill = [[Person alloc] init];
[Link] = @"Bill";
Person *mary = [[Person alloc] init];
[Link] = @"Mary";
[joe sayHello];
[joe addFriend:bill];
[joe addFriend:mary];
[joe sayHelloToFriends];
}
20
}
Extensions
• A class extension is similar to a category, but it can only be added to a class for which
you have the source code at compile time.
• The methods declared by a class extension are implemented in the implementation
block for the original class.
• Extensions are actually categories without the category name.
It's often referred as anonymous categories.
• The syntax to declare a extension uses the @interface keyword.
• Syntax
@interface ClassName ()
@end
Characteristics of extensions
• An extension cannot be declared for any class, only for the classes that we have
original implementation of source code.
• An extension is adding private methods and private variables that are only
specific to the class.
• Any method or variable declared inside the extensions is not accessible
even to the inherited classes.
Example
@interface SampleClass : NSObject
{
NSString *name;
}
- (void)setInternalID;
- (NSString *)getExternalID;
21
@end
@interface SampleClass()
{
NSString *internalID;
}
@end
@implementation SampleClass
- (void)setInternalID
{
internalID=[NSStringstringWithFormat:
@"UNIQUEINTERNALKEY%dUNIQUEINTERNALKEY",arc4r
andom()%100];
}
- (NSString *)getExternalID
{
return[internalIDstringByReplacingOccurrencesOfString:
@"UNIQUEINTERNALKEY" withString:@""];
}
@end
The following table 3.1 shows the Difference between Category & Extension.
22
It helps to add some more It helps to add some more functionality to
functionality to existing class, existing class, but only properties and
but only functions instance variables
It come with its own .h and .m file It comes with .m file only
Fast Enumeration-NSArray
• NSArray is general-purpose array type.
• It represents an ordered collection of objects.
• Like NSSet, NSArray is immutable, so you cannot dynamically add
or remove items.
• Immutable arrays can be defined as literals using the @[] syntax.
23
are guaranteed to appear in the correct order.
Eg.
NSArray *germanMakes = @[@"Mercedes- Benz", @"BMW", @"Porsche", @"Opel",
@"Volkswagen", @"Audi"];
// With fast-enumeration
for (NSString *item in germanMakes)
{
NSLog(@"%@", item);
}
// With a traditional for loop
for (int i=0; i<[germanMakes count]; i++)
{
NSLog(@"%d: %@", i, germanMakes[i]);
}
There are several advantages to using fast enumeration:
– The enumeration is considerably more efficient than, for The
syntax is concise
– Enumeration is “safe”—the enumerator has a mutation guard so that if
you attempt to modify the collection during enumeration, an exception is
raised
• The NSDictionary class represents an unordered collection of objects
• They associate each value with a key, which acts like a label for the value.
This is useful for modeling relationships between pairs of objects
• NSDictionary is immutable, but the NSMutableDictionary data structure lets you
dynamically add and remove entries as necessary.
• Immutable dictionaries can be defined using the
literal @{} syntax.
• Factory methods
– dictionaryWithObjectsAndKeys:
– dictionaryWithObjects:forKeys:
Eg.
24
// Literal syntax
NSDictionary *inventory = @{ @"Mercedes-Benz SLK250" : [NSNumber
numberWithInt:13],
@"Mercedes-Benz E350" : [NSNumber numberWithInt:22],
@"BMW M3 Coupe" : [NSNumber numberWithInt:19], @"BMW X6" : [NSNumber
numberWithInt:16], };
Eg.
// Values and keys as arguments
inventory = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:13], @"Mercedes-Benz SLK250",
[NSNumber numberWithInt:22], @"Mercedes-Benz E350",
[NSNumber numberWithInt:19], @"BMW M3 Coupe", [NSNumber numberWithInt:16],
@"BMW X6", nil];
Eg.
// Values and keys as arrays
NSArray *models = @[@"Mercedes-Benz SLK250", @"Mercedes-Benz E350", @"BMW
M3 Coupe", @"BMW X6"];
NSArray *stock = @[[NSNumber numberWithInt:13], [NSNumber numberWithInt:22],
[NSNumber numberWithInt:19], [NSNumber numberWithInt:16]];
inventory = [NSDictionary dictionaryWithObjects:stock forKeys:models];
NSLog(@"%@", inventory);
• Fast-enumeration is the most efficient way to enumerate a dictionary, and it loops
through the keys (not the values).
• NSDictionary also defines a count method, which returns the number of entries in the
collection.
Eg.
NSLog(@"We currently have %ld models available", [inventory count]);
for (id key in inventory) {
NSLog(@"There are %@ %@'s in stock", inventory[key], key); }
25
• A selector refers to the name used to select a method to execute for an object
• It is used to identify a method
– Compiler writes each method name into a table
– Pairs the name with a unique identifier that represents the method at runtime
– The runtime system makes sure each identifier is unique
– No two selectors are the same, and all methods with the
same name have the same selector
Static Class
• A class is a blue print for the members like, static variable and static methods.
• A static variable are declared using the modifier static.
• Syntax
• static <data_type> <variable_name>;
Eg.
static int number;
For static method which is also known as class method, you can use the + sign instead of
the – sign when declaring the method.
• Syntax
+ (data_type)method_name;
Eg. +(int) getNumber;
Dynamic Objects
• Dynamic binding is determining the method to invoke at runtime instead of at compile
time. Dynamic binding is also referred to as late binding.
• In Objective-C, all methods are resolved dynamically at runtime.
• The exact code executed is determined by both the method name (the selector) and
the receiving object.
• Dynamic binding enables polymorphism.
Eg.
– Consider a collection of objects including Rectangle and Square.
– Each object has its own implementation of a printArea method.
26
– The actual code that should be executed by the expression [anObject
printArea] is determined at runtime.
– In this, printArea method is dynamically selected in runtime.
Example
#import <Foundation/Foundation.h>
@interface Square:NSObject
{
float area;
}
- (void)calculateAreaOfSide:(CGFloat)side;
- void)printArea;
@end
@implementation Square
- (void)calculateAreaOfSide:(CGFloat)side
{
area = side * side;
}
-(void)printArea
{
NSLog(@"The area of square is %f",area);
}
@end
@interface Rectangle:NSObject
{
float area;
}
- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth;
- (void)printArea;
@end
@implementation Rectangle
- (void)calculateAreaOfLength:(CGFloat)length andBreadth:(CGFloat)breadth
27
{
area = length * breadth;
}
- (void)printArea
{
NSLog(@"The area of Rectangle is %f",area); }
@end
int main()
{
Square *square = [[Square alloc]init];
[square calculateAreaOfSide:10.0];
Rectangle *rectangle = [[Rectangle alloc]init];
[rectangle calculateAreaOfLength:10.0 andBreadth:5.0];
NSArray *shapes = [[NSArray alloc]initWithObjects: square, rectangle,nil];
id object1 = [shapes objectAtIndex:0];
[object1 printArea];
id object2 = [shapes objectAtIndex:1];
[object2 printArea];
return 0;}
Exception Handling
• An exception is a special condition that interrupts the normal flow of program
execution
• There are a variety of reasons why an exception may be generated, by hardware as
well as software
• Exception handling is made available in Objective- C with foundation class
NSException
• Objective-C exception support four compiler directives:
– @try - This block tries to execute a set of statements
– @catch - This block tries to catch the exception in try block
– @throw - throw exceptions if you find yourself in a situation that indicates
a programming error, and want to stop the application from running
28
– @finally - This block contains set of statements that always execute
Eg. division by zero, underflow or overflow, calling undefined instructions
#import <Foundation/Foundation.h>
int main()
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [[NSMutableArray alloc]init];
@try
{
NSString *string = [array objectAtIndex:10];
}
@catch (NSException *exception)
{
NSLog(@"%@ ",[Link]);
NSLog(@"Reason: %@ ",[Link]);
}
@finally
{
NSLog(@"@finaly Always Executes");
}
[pool drain];
return 0;}
Memory Management
• Objects reside in memory, and especially on mobile devices this is a scarce resource
• To make sure that programs don’t take up any more space than they need
• The goal of any memory management system is to reduce the memory footprint of
a program by controlling the lifetime of all its objects. iOS and OS X applications
accomplish this through object ownership, which makes sure objects exist as long
as they have to, but no longer
• Many languages accomplish this through garbage collection, but Objective-C uses
object ownership
29
Figure 3.6 Memory management in Objective C
Manual Retain Release environment
• alloc - Create an object and claim ownership of it.
• retain - Claim ownership of an existing object.
• copy - Copy an object and claim ownership of it.
• release - Relinquish ownership of an object and destroy it immediately.
• autorelease - Relinquish ownership of an object but defer its destruction.
• Manually controlling object ownership might seem like a daunting task, but it’s
actually very easy.
• All you have to do is claim ownership of any object you need and remember to
relinquish ownership when you’re done with it.
• When you forget to balance these calls, one of two things can happen.
– If you forget to release an object, its underlying memory is never freed,
resulting in a memory leak.
– “mall leaks won’t have a visible effect on your program, but if you eat up
enough memory, your program will eventually crash.
– On the other hand, if you try to release an object too many times, you’ll have what’s
called a dangling pointer.
– When you try to access the dangling pointer, you’ll be requesting an invalid
memory address, and your program will most likely crash.
30
Figure 3.7 Balance between memory leak and dangling pointer
31
The Retain Method
• The retain method claims ownership of an existing object.
• It’s like telling the operating system, “Hey! I
need that object too, so don’t get rid of it!”.
destroying the object immediately, it defers the actual freeing of memory until
later on in the program.
• This allows you to release objects when you are “supposed”
to, while still keeping them around for others to use.
Eg.
// CarStore.h
32
+ (CarStore *)carStore;
// CarStore.m
+ (CarStore *)carStore
{
CarStore *newStore = [[CarStore alloc] init];
return [newStore autorelease];
}
The dealloc Method
• An object’s dealloc method is the opposite of its init method.
• It’s called right before the object is destroyed, giving you a
chance to clean up any internal objects.
• This method is called automatically by the runtime—you should
never try to call dealloc yourself.
• Eg.
// CarStore.m
(void)dealloc
{
[_inventory release];
[super dealloc];
}
• Automatic Reference Counting works the exact same way as MRR, but it
automatically inserts the appropriate memory- management methods for
you.
• This is a big deal for Objective-C developers, as it lets them focus entirely
on what their application needs to do rather than how it does it.
• ARC takes the human error out of memory management with virtually no
downside, so the only reason not to use it is when you’re interfacing with a
legacy code base.
• The rest of this module explains the major changes between MRR and ARC
• Enabling ARC
– First, let’s go ahead and turn ARC back on in the project’s Build Settings tab as
shown in figure 3.9.
33
– Change the Automatic Reference Counting compiler option to Yes.
– Again, this is the default for all Xcode templates, and it’s what you should be
using for all of your projects
34
– It makes sure the value exists as long as it’s assigned to the property
35
Required Tools
• Objective-C is the native programming language for Apple’s iO“ and O“ X
operating systems.
• It’s a compiled, general-purpose language capable of building everything from
command line utilities to animated GUIs to domain- specific libraries.
• It also provides many tools for maintaining large, scalable frameworks.
36
• Finally, Build and run your apps
37
• This will open a dialog window asking you to select a
template:
Figure 3.14 Creating a command line application
• This opens another dialog asking you to configure the project:
38
Figure 3.16 main.m in the Project Navigator
• To compile the project, click the Run button in the upper-left corner of the IDE or use
the Cmd+R shortcut.
• This should display Hello, World!in the Output Panel located at the bottom of the
IDE as shown in figure 3.17
39
iOS Simulator
• The iOS Simulator app, available within Xcode, presents the iPhone, iPad, or Apple
Watch user interface in a window on your Mac computer.
• You interact with iOS Simulator by using the keyboard and the mouse to emulate
taps, device rotation, and other user actions.
• There are two different ways to access iOS Simulator through Xcode.
– The first way is to run your app in iOS Simulator.
– The second way is to launch iOS Simulator without running an app.
Running Your App in iOS Simulator
• When testing an app in iOS Simulator, it is easiest to launch and run your app in iOS
Simulator directly from your Xcode project.
• To run your app in iOS Simulator, choose an iOS simulator—for example, iPhone 6
or iPad Air—from the Xcode scheme pop-up menu and click Run.
• Xcode builds your project and then launches the most recent version of your app
running in iOS Simulator on your Mac screen as shown in figure 3.18
40
• Incorporating Instruments into your workflow from the beginning of the app
development process can save you time later by helping you find issues early in the
development cycle.
• In Instruments, you use specialized tools, known as instruments, to trace different
aspects of your apps, processes, and devices over time.
• Instruments collects data as it profiles, and presents the results to you in detail for
analysis.
• By using Instruments effectively, you can:
– Examine the behavior of one or more apps or processes
– Examine device-specific features, such as Wi-Fi and Bluetooth
– Perform profiling in a simulator or on a physical device
– Create custom DTrace instruments to analyze aspects of system and app
behavior
– Track down problems in your source code
– Conduct performance analysis on your app
– Find memory problems in your app, such as leaks, abandoned memory, and
zombies
– Identify ways to optimize your app for greater power efficiency
– Perform general system-level troubleshooting
– Automate testing of your iOS app by running custom scripts to perform a
sequence of user actions and replaying them to reliably reproduce those events
and collect data over multiple runs
– Save instrument configurations as templates
The Instruments Workflow
42
ARC
• Automatic Reference Counting (ARC) to track and manage your app’s memory usage.
• Every time you create a new instance of a class, ARC allocates a chunk of memory to
store information about that instance.
• This memory holds information about the type of the instance, together with the values
of any stored properties associated with that instance.
• Additionally, when an instance is no longer needed, ARC frees up the memory used by
that instance so that the memory can be used for other purposes instead.
• This ensures that class instances do not take up space in memory when they are no longer
needed.
• ARC were to deallocate an instance that was still in use, it would no longer be possible
to access that instance’s properties, or call that instance’s methods.
• Indeed, if you tried to access the instance, your app would most likely crash.
• ARC tracks how many properties, constants, and variables are currently referring to each
class instance.
• ARC will not deallocate an instance as long as at least one active reference to that
instance still exists.
• To make this possible, whenever you assign a class instance to a property, constant, or
variable, that property, constant, or variable makes a strong reference to the instance.
• The reference is called a “strong“ reference because it keeps a firm hold on that instance,
and does not allow it to be deallocated for as long as that strong reference remains.
Framework
• A framework is a collection of resources; it collects a static library and its header files
into a single structure that Xcode can easily incorporate into your projects.
• The Foundation framework defines a base layer of Objective-C classes.
• In addition to providing a set of useful primitive object classes, it introduces several
paradigms that define functionality not covered by the Objective-C language.
• The Foundation framework is designed with these goals in mind:
– Provide a small set of basic utility classes
– Make software development easier by introducing consistent conventions
for things such as deallocation
– Support Unicode strings, object persistence, and object distribution
43
• Provide a level of OS independence to enhance portability The framework was
developed by NeXTStep, which was acquired by Apple and these foundation classes
became part of Mac OS X and iOS.
• Since it was developed by NeXTStep, it has class prefix of “NS”.
• We have used Foundation Framework in all our sample programs. It is almost a must
to use Foundation Framework.
• Generally, we use something like
#import<Foundation/NSString.h> to import an Objective-C class, but in order avoid
importing too many classes, it's all imported in
#import<Foundation/Foundation.h>.
• NSObject is the base class of all objects including the foundation kit classes. It
provides the methods for memory management.
• It also provides basic interface to the runtime system and ability to behave as
Objective-C objects. It doesn't have any base class and is the root for all classes.
Table 3.3 Foundation Classes based on functionality
Loop Type Description
Data storage NSArray, NSDictionary, and NSSet provide storage for
Objective-C objects of any class.
Text and strings NSCharacterSet represents various groupings of characters
that are used by the NSString and NSScanner classes.
The NSString classes represent text strings and provide
methods for searching, combining, and comparing strings.
An NSScanner object is used to scan numbers and words
from an NSString object.
Dates and times The NSDate, NSTimeZone, and NSCalendar classes store
times and dates and represent calendrical information. They
offer methods for calculating date and time differences.
Together with NSLocale, they provide methods for
displaying dates and times in many formats and for adjusting
times and dates based on location in the world.
44
Exception handling Exception handling is used to handle unexpected situations
and it's offered in Objective-C with NSException.
File handling File handling is done with the help of class NSFileManager.
URL loading system A set of classes and protocols that provide access to
common Internet protocols.
45
SCHOOL OF COMPUTING
Unit – IV
Introduction to iOS – History, Versions and Features - MVC Architecture - View
Controller - Building the UI - Event handling - Application life cycle - Tab Bars - Story
Boards - Navigation Controllers - Push Notification - Database handling - Debugging and
Deployment - Publishing app in Appstore.
1
Introduction to IOS
Operating system is a set of programs that manage computer hardware resources and
provide common services for application software important system software in computer
system. User cannot run an application program on computer without OS. i.e. Android,
Mac OS X, Microsoft Windows. Apples mobile operating system considered the
foundation of the iPhone Originally designed for the iPhone but now supports iPod touch,
iPad, and Apple TV It is updated just like Itune for iPods As of Oct 2011 Apple contains
over 500,000 iOS applications.
History
iPhone OS was first unveiled in Jan 2007 at the Macworld Conference and Expo Released
June [Link] June 2010 licensed the trademark iOS (From Cisco IOS). Now goes all the
way up to iOS 5. Originally did not allow third party applications but after Feb 2008 this
changed. With either 30% profit to apple, or free with membership fee. The following
figure 4.1 shows the features of IOS.
Features
The power of iOS can be felt with some of the following features provided as a part of the
device.
➢ Maps
➢ Siri
2
➢Facebook and Twitter
➢ Multi-Touch
➢ Accelerometer
➢ GPS
➢ High end processor
➢ Camera
➢ Safari
➢ Powerful APIs
➢ Game center
➢ In-App Purchase
➢ Reminders
The primary applications consist of
➢ Safari
➢ Music
➢ Mail
➢ Phone, Face Time
The secondary applications consist of
➢ Camera, Camcorder
➢ Photos
➢ Calendar
➢ Messaging
➢ WeTube
➢ Stocks
➢ Map
➢ Clock
Environmental Setup
iOS - Xcode Installation
Interface Builder
Interface builder is the tool that enables easy creation of UI interface. We have a
rich set of UI elements that is developed for use. We just have to drag and drop into our
UI view. We'll learn about adding UI elements, creating outlets and actions for the UI
elements in the upcoming pages.
Step 1 : First, launch Xcode. If we’ve installed Xcode via Mac App Store, we should be
able to locate Xcode in the LaunchPad. Just click on the
Step 2: Once launched, Xcode displays a welcome dialog. From here, choose “Create a
new
4
5
We can simply fill in the options as follows:
• Company Identifier: com. appcoda – It’s actually the domain name written the other way
round. If we have a domain, we can use our own domain name. Otherwise, we may use
mine or just fill in “[Link]”.
• Class Prefix: HelloWorld – Xcode uses the class prefix to name the class automatically. In
future, we may choose our own prefix or even leave it blank. But for this tutorial, let’s
keep it simple and use “HelloWorld”.
• Device Family: iPhone – Just use “iPhone” for this project.
• Use Storyboards: [unchecked] – Do not select this option. We do not need Storyboards for
this simple project.
• Use Automatic Reference Counting: [checked] – By default, this should be enabled. Just
leave it as it is.
• Include Unit Tests: [unchecked] – Leave this box unchecked. For now, we do not need the
unit test class.
Step 4: Click “Next” to continue. Xcode then asks us where to save the “Hello.
6
7
The rightmost pane is the utility area. This area displays the properties of the file and
allows we to access Quick Help. If Xcode doesn’t show this area, we can select the
rightmost view button in the toolbar to enable it.
Step 7: Add the Hello World button to our app. Go back to the Project Navigator and
select “[Link]”.
The editor changes to an Interface Builder and displays an empty view of our app like
below.
8
Step 8: In the lower part of the utility area, it shows the Object library. From here, we can
choose any of the UI Controls, drag-and-drop it into the view. For the Hello World app,
let’s pick the “Round Rect Button” and drag it into the view. Try to place the button at the
center of the view. To edit the label of the button, double-click it and name it “Hello
World”.
In the Project Navigator, select the “HelloWorldViewController.h”. The editor area now
displays the source code of the selected file. Add the following line of code before the
“@endline.
9
Step 10: Next, select the “HelloWordViewController.m” and insert the following code
before the “@endline”.
- (IBAction)showMessage
{
UIAlertView *helloWorldAlert = [[UIAlertView alloc]
initWithTitle:@"My First App" message:@"Hello, World!" delegate:nil
cancelButtonTitle:@"OK" otherButtonTitles:nil];
[helloWorldAlert show];
}
we’ll need to establish a connection between the “Hello World” button and the
“showMessage” action we’ve just added. Select the “[Link]” file
to go back to the Interface Builder. Press and hold the Control key on our keyboard, click
the “Hello World” button and drag to the “File’s Owner”. Our screen should look like this:
10
Step 12: Test Our App
Just hit the “Run” button. If everything is correct, our app should run properly in the
Simulator. An iOS simulator actually consists of two types of devices, namely iPhone and
iPad with their different versions. iPhone versions include iPhone (normal), iPhone Retina,
iPhone 5. iPad has iPad and iPad Retina. We can simulate location in an iOS simulator for
playing around with latitude and longitude effects of the app. We can also simulate
memory warning and in-call status in the simulator. We can use the simulator for most
purposes, however we cannot test
device features like accelerometer.
Model-View-Controller
The Model-View-Controller design pattern (MVC) is quite old. Variations of it have
been around at least since the early days of Smalltalk. It is a high-level pattern in that it
concerns itself with the global architecture of an application and classifies objects
according to the general roles they play in an application. It is also a compound pattern in
that it comprises several, more elemental patterns. The MVC design pattern considers there
to be three types of objects: model objects, view objects, and controller objects. The MVC
pattern defines the roles that these types of objects play in the application and their lines
of communication.
Model Object
Model objects represent special knowledge and expertise. They hold an application’s
data and define the logic that manipulates that data. A well-designed MVC application has
11
all its important data encapsulated in model objects. Any data that is part of the persistent
state of the application (whether that persistent state is stored in files or databases) should
reside in the model objects once the data is loaded into the application. Because they
represent knowledge and expertise related to a specific problem domain, they tend to be
reusable.
View Objects
A view object knows how to display, and might allow users to edit, the data from the
application’s model. The view should not be responsible for storing the data it is
displaying. A view object can be in charge of displaying just one part of a model object,
or a whole model object, or even many different model objects. Views come in many
different [Link] objects tend to be reusable and configurable, and they provide
consistency between applications. A view should ensure it is displaying the model
correctly.
Controller Objects
A controller object acts as the intermediary between the application's view objects
and its model objects. Controllers are often in charge of making sure the views have access
to the model objects they need to display and act as the conduit through which views learn
about changes to the model. Controller objects can also perform set-up and coordinating
tasks for an application and manage the life cycles of other objects. Model-View-
Controller is a design pattern that is composed of several more basic design patterns. These
basic patterns work together to define the functional separation and paths of
communication that are characteristic of an MVC application. MVC is made up of the
Composite, Strategy, and Observer patterns.
• Composite—The view objects in an application are actually a composite of nested
views that work together in a coordinated fashion (that is, the view hierarchy). These
display components range from a window to compound views, such as a table view, to
individual views, such as buttons. User input and display can take place at any level of the
composite structure.
• Strategy—A controller object implements the strategy for one or more view
objects. The view object confines itself to maintaining its visual aspects, and it delegates
to the controller all decisions about the application-specific meaning of the interface
behavior.
• Observer—A model object keeps interested objects in an application—usually
12
view objects—advised of changes in its state.
A controller object receives the event and interprets it in an application-specific
way— that is, it applies a strategy. This strategy can be to request (via message) a model
object to change its state or to request a view object (at some level of the composite
structure) to change its behavior or appearance. The model object, in turn, notifies all
objects who have registered as observers when its state changes; if the observer is a view
object, it may update its appearance accordingly. The following figure 4.2 shows the MVC
design patterns.
A user needs to interact with an app interface in the simplest way possible. Design
the interface with the user in mind, and make it efficient, clear, and straightforward.
Storyboards let we design and implement our interface in a graphical environment. We see
exactly what we're building while we’re building it, get immediate feedback about what’s
working and what’s not, and make instantly visible changes to our interface. They are the
building blocks for constructing our user interface and presenting our content in a clear,
elegant, and useful way. As we develop more complex apps, we'll create interfaces with
more scenes and more views. The following figure 4.3 shows the MVC architecture.
13
Figure 4.3 MVC Architecture
One can merge the MVC roles played by an object, making an object, for example,
fulfill both the controller and view roles—in which case, it would be called a view
controller.
A model controller is a controller that concerns itself mostly with the model layer.
It “owns” the model; its primary responsibilities are to manage the model and
communicate with view objects. Action methods that apply to the model as a whole are
typically implemented in a model controller. The document architecture provides a number
of these methods for we; for example, an NSDocument object (which is a central part of
the document architecture) automatically handles action methods related to saving files.
A view controller is a controller that concerns itself mostly with the view layer. It
“owns” the interface (the views); its primary responsibilities are to manage the interface
and communicate with the model. Action methods concerned with data displayed in a view
are typically implemented in a view controller. An NSWindowControllerobject (also part
of the document architecture) is an example of a view controller.
A coordinating controller is typically an NSWindowController or
NSDocumentControllerobject (available only in AppKit), or an instance of a custom
subclass of NSObject. Its role in an application is to oversee—or coordinate—the
functioning of the entire application or of part of the application, such as the objects
unarchived from a nib file. A coordinating controller provides services such as:
• Responding to delegation messages and observing notifications
• Responding to action messages
• Managing the life cycle of owned objects (for example, releasing them at the proper time)
• Establishing connections between objects and performing other set-up tasks
14
View Controller
A view controller is a controller that concerns itself mostly with the view layer. It “owns”
the interface (the views); its primary responsibilities are to manage the interface and
communicate with the model. Action methods concerned with data displayed in a view are
typically implemented in a view controller. An NSWindowControllerobject (also part of
the document architecture) is an example of a view controller.
Views not only display themselves onscreen and react to user input, they can serve
as containers for other views. As a result, views in an app are arranged in a hierarchical
structure called the view hierarchy. The view hierarchy defines the lawet of views relative
to other views. Within that hierarchy, views enclosed within a view are called sub views,
and the parent view that encloses a view is referred to as its super view. Even though a
view can have multiple sub views, it can have only one super view.
At the top of the view hierarchy is the window object. Represented by an instance
of the UIWindow class, a window object is the basic container into which we add our view
objects for display onscreen. By itself, a window doesn’t display any content.
To display content, we add a content view object (with its hierarchy of sub views)
to the window. For a content view and its sub views to be visible to the user, the content
view must be inserted into a window’s view hierarchy. When we use a storyboard, this
placement is configured automatically for we. When an app launches, the application
object loads the storyboard, creates instances of the relevant view controller classes, un
archives the content view hierarchies for each view controller, and then adds the content
view of the initial view controller into the window.
Types of Views
A UIKit view object is an instance of the UIView class or one of its subclasses.
The UIKit framework provides many types of views to help present and organize data as
shown in figure 4.4. Although each view has its own specific function, UIKit views can
be grouped into these general categories.
15
Figure 4.4 Type of view objects
16
Figure 4.5 View Controller
17
Figure 4.6 Inspection Pane
Use the Auto Lawet icons in the bottom-right area of our canvas to add various
types of constraints to views on our canvas, resolve lawet issues, and determine constraint
resizing behavior.
• Align. Create alignment constraints, such as centering a view in its container, or
aligning the left edges of two views.
• Pin. Create spacing constraints, such as defining the height of a view, or
specifying its horizontal distance from another view.
• Resolve Auto Lawet Issues. Resolve lawet issues by adding or resetting
constraints based on suggestions.
• Resizing Behavior. Specify how resizing affects constraints.
18
Figure 4.7 Auto Lawet Icons
Building UI
UI elements are the visual elements that we can see in our applications. Some of
these elements respond to user interactions such as buttons, text fields and others are
informative such as images, labels.
Use of Text Field
A text field is a UI element that enables the app to get user input. A UITextfield is
shown in figure 4.8. The table 4.1 shows the different UI input types along with its
descriptions.
19
• Key board type
• Return key type
• Clear button mode
• Alignment
• Delegate
Table 4.1 UI Input Types
Buttons
Buttons are used for handling user actions. It intercepts the touch events and sends message
to the target object.
Buttons Types
• UIButtonTypeCustom
• UIButtonTypeRoundedRect
• UIButtonTypeDetailDisclosure
• UIButtonTypeInfoLight
• UIButtonTypeInfoDark
• UIButtonTypeContactAdd
Code
-(void)addDifferentTypesOfButton
{ // A rounded Rect button created by using class method
UIButton *roundRectButton = [UIButton buttonWithType: UIButtonTypeRoundedRect];
[roundRectButton setFrame:CGRectMake(60, 50, 200, 40)]; // sets title for the button
20
[roundRectButton setTitle:@"Rounded Rect Button" forState: UIControlStateNormal];
[[Link] addSubview:roundRectButton];
Labels
Labels are used for displaying static content, which consists of a single line or multiple
lines as shown in figure 4.9.
Important Properties
• textAlignment
• textColor
• text
• numberOflines
• lineBreakMode
- (void)addLabel
{ UILabel *aLabel = [[UILabel alloc]initWithFrame: CGRectMake(20, 200, 280, 80)];
[Link] = 0;
[Link] = [UIColor blueColor];
[Link] = [UIColor clearColor];
[Link] = UITextAlignmentCenter;
[Link] = @"This is a sample text\n of multiple lines. here number of lines is
not limited.";
[[Link] addSubview:aLabel];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self addLabel]; }
Image View
Image view is used for displaying a single image or animated sequence of images.
Important Properties
• image
• highlightedImage
• userInteractionEnabled
• animationImages
• animationRepeatCount
Important Methods
- (id)initWithImage:(UIImage*)image
- (id)initWithImage:(UIImage *)image highlightedImage: (UIImage
*)highlightedImage
- (void)startAnimating
- (void)stopAnimating
[[Link] addSubview:imgview];
}
Scroll View
Scroll View is used for displaying content more than the size of the screen. It can
contain all of the other UI elements like image views, labels, text views and even another
scroll view itself as shown in figure 4.12.
Important Properties
• contentSize
• contentInset
• contentOffset
• delegate
Code
-(void)addScrollView
{
myScrollView = [[UIScrollView alloc]initWithFrame: CGRectMake(20, 20, 280, 420)];
[Link] = CGPointMake(100, 100);
imgView = [[UIImageView alloc]initWithImage: [UIImage
imageNamed:@"[Link]"]];
[myScrollView addSubview:imgView];
[Link] = 0.5; [Link] = 3;
[Link] = CGSizeMake([Link],
[Link]);
24
Figure 4.12 UI Element – Scroll View
Table View
It is used for displaying a vertically scrollable view which consists of a number of
cells (generally reusable cells). It has special features like headers, footers, rows, and section.
Important Properties
• Delegate
• Data source
• Row height
• Section footer height
• Section header height
• Separator color
• Table header view
• Table footer view
Code
- @interface ViewController ()
- @end
- @implementation ViewController
- (void)viewDidLoad
- {
25
- [super viewDidLoad]; // table view data is being set here
- myData = [[NSMutableArray alloc]initWithObjects:
- @"Data 1 in array",
- @"Data 2 in array",
- @"Data 3 in array",
- @"Data 4 in array",
- @"Data 5 in array",
- @"Data 5 in array",
- @"Data 6 in array",
- @"Data 7 in array",
- @"Data 8 in array",
- @"Data 9 in array", nil];
View Transitions
View Transitions are effective ways of adding one view on another view with a proper
transition animation effect as shown in figure 4.13.
Pickers
Pickers consist of a rotating scrollable view, which is used for picking a value from
the list of items. It is shown in figure 4.14.
Important Properties
26
• delegate
• dataSource
Switches
Switches are used to toggle between on and off states.
Important Properties
• onImage
• offImage
• on
Important Method
- (void)setOn:(BOOL)on animated:(BOOL)animated
-(IBAction)switched:(id)sender
{
NSLog(@"Switch current state %@", [Link] ? @"On": @"Off");
}
-(void)addSwitch
{
mySwitch = [[UISwitch alloc] init]; [[Link] addSubview:mySwitch]; [Link]
= CGPointMake(150, 200);
27
[mySwitch addTarget:self action:@selector(switched:)
forControlEvents:UIControlEventValueChanged];
}
Sliders
Sliders are used to choose a single value from a range of values as shown in figure
4.15.
Important Properties
• Continuous
• Maximum Value
• Minimum Value
• Value
Important Method
- (void)setValue:(float)value animated:(BOOL)animated
Code
-(IBAction)sliderChanged:
(id)sender
{
NSLog(@"SliderValue %f",[Link]);
}
-(void)addSlider
{
[Link] = 10.0;
[Link] = 99.0; [Link] = NO;
28
Figure 4.15 UI Element – Sliders
Alerts
Alerts are used to give important information to user. Only after selecting the
option in the alert view, we can proceed further using the app. It is shown in figure 4.16.
Important Properties
• Alert View Style
• Cancel Button Index
• Delegate message
• Number of Buttons
• Title
Code
(NSInteger)addButtonWithTitle:(NSString *)title
- (NSString *)buttonTitleAtIndex:(NSInteger)buttonIndex
- (void)dismissWithClickedButtonIndex: (NSInteger)buttonIndex animated:
(BOOL)animated
- - (void)show
29
Figure 4.16 UI Element – Alerts
Event Handling
Users manipulate their iOS devices in a number of ways, such as touching the
screen or shaking the device. iOS interprets when and how a user is manipulating the
hardware and passes this information to our app. The more our app responds to actions in
natural and intuitive ways, the more compelling the experience is for the user.
Events are objects sent to an app to inform it of user actions. In iOS, events can
take many forms: Multi-Touch events, motion events, and events for controlling
multimedia. This last type of event is known as a remote-control event because it can
originate from an external accessory.
iOS apps recognize combinations of touches and respond to them in ways that are
intuitive to users, such as zooming in on content in response to a pinching gesture and
scrolling through content in response to a flicking gesture. In fact, some gestures are so
common that they are built in to UIKit. For example, UIControl subclasses, such as
UIButton and UISlider, respond to specific gestures—a tap for a button and a drag for a
slider. When we configure these controls, they send an action message to a target object
when that touch occurs. We can also employ the target-action mechanism on views by
using gesture recognizers. When we attach a gesture recognizer to a view, the entire view
acts like a control—responding to whatever gesture we specify.
30
logic. Gesture recognizers are the preferred way to implement touch-event handling in our
app because gesture recognizers are powerful, reusable, and adaptable. We can use one of
the built-in gesture recognizers and customize its behavior. Or we can create our own
gesture recognizer to recognize a new gesture.
Gesture Recognizers
When iOS recognizes an event, it passes the event to the initial object that seems
most relevant for handling that event, such as the view where a touch occurred. If the initial
object cannot handle the event, iOS continues to pass the event to objects with greater
scope until it finds an object with enough context to handle the event. This sequence of
objects is known as a responder chain, and as iOS passes events along the chain, it also
transfers the responsibility of responding to the event. This design pattern makes event
handling cooperative and dynamic.
Multitouch Events
Depending on our app, UIKit controls and gesture recognizers might be sufficient
for all of our app’s touch event handling. Even if our app has custom views, we can use
gesture recognizers. As a rule of thumb, we write our own custom touch-event handling
when our app’s response to touch is tightly coupled with the view itself, such as drawing
under a touch. In these cases, we are responsible for the low-level event handling. We
implement the touch methods, and within these methods, we analyze raw touch events and
respond appropriately.
Motion Events
Motion events provide information about the device’s location, orientation, and
movement. By reacting to motion events, we can add subtle, yet powerful features to our
app. Accelerometer and gyroscope data allow us to detect tilting, rotating, and shaking.
Motion events come in different forms, and we can handle them using different
frameworks. When users shake the device, UIKit delivers a UIEvent object to an app. If
we want our app to receive high-rate, continuous accelerometer and gyroscope data, use
the Core Motion framework.
31
Remote Control Events
IOS controls and external accessories send remote control events to an app. These
events allow users to control audio and video, such as adjusting the volume through a
headset. Handle multimedia remote control events to make our app responsive to these
types of commands.
The figure 4.17 shows the architecture of the main run loop and how user events result in
actions taken by our app. As the user interacts with a device, events related to those
interactions are generated by the system and delivered to the app via a special port set up
by UIKit. Events are queued internally by the app and dispatched one-by-one to the main
run loop for execution. The UIApplication object is the first object to receive the event and
make the decision about what needs to be done. A touch event is usually dispatched to the
main window object, which in turn dispatches it to the view in which the touch occurred.
Other events might take slightly different paths through various app objects. The table 4.2
shows the various types of Events.
32
Table 4.2 Events and its types
Event Delivered to Description
The view object in Views are responder objects. Any touch
Touch
which the event events not handled by the view are
occurred forwarded down the responder chain for
processing.
Remote control Remote control events are for controlling
First responder
Shake motion media playback and are generated by
object
events headphones and other accessories.
Accelerometer Events related to the accelerometer,
The object we
Magnetometer magnetometer, and gyroscope hardware
designate
Gyroscope are delivered to the object
We designate.
Location The object we We register to receive location events
designate using the Core Location
framework.
Redraw Redraw events do not involve
The view that
an event object but are simply calls to the
needs the
view to draw itself.
update
The view object in Views are responder objects. Any touch
Touch
which the event events not handled by the view are
occurred forwarded down the responder chain for
processing.
Some events, such as touch and remote-control events, are handled by our app’s
responder objects. Responder objects are everywhere in our app. Most events target a
specific responder object but can be passed to other responder objects (via the responder
chain) if needed to handle an event. For example, a view that does not handle an event can
pass the event to its super view or to a view controller.
Touch events occurring in controls (such as buttons) are handled differently than
touch events occurring in many other types of views. There are typically only a limited
number of interactions possible with a control, and so those interactions are repackaged into
33
action messages and delivered to an appropriate target object. This target-action design
pattern makes it easy to use controls to trigger the execution of custom code in our app.
State Description
Not running The app has not been launched or was running but was terminated
by the system.
The app is in the background and executing code. Most apps enter
this state briefly on their way to being suspended. However, an app
Background
that requests extra execution time may remain in this state for a
period of time. In addition, an app being launched directly into the
background enters this state instead of the inactive state.
The app is in the background but is not executing code. The system
Suspended
moves apps to this state automatically and does not notify them
before doing so. While suspended, an app remains in memory but
does not execute any code. When a low-memory condition occurs,
34
the system may purge suspended apps without notice to make more
space for the foreground app.
A tab bar controller is a container view controller that we use to divide our app into
two or more distinct modes of operation. A tab bar controller is an instance of the
UITabBarController class. The tab bar has multiple tabs, each represented by a child view
controller. Selecting a tab causes the tab bar controller to display the associated view
controller’s view on the screen. The figure 4.19 shows several modes of the Clock app along
with the relationships between the corresponding view controllers. Each mode has a content
view controller to manage the main content area. In the case of the Clock app, the Clock and
Alarm view controllers both display a navigation-style interface to accommodate some
additional controls along the top of the screen. The other modes use content view controllers
to present a single screen.
35
Figure 4.19 Tab bar Controller
Navigation Controllers
stack-based collection of content view controllers. This stack represents the path taken by
the user through the hierarchical data, with the bottom of the stack reflecting the starting
point and the top of the stack reflecting the user’s current position in the data.
The figure 4.20 shows screens from the Contacts app, which uses a navigation
controller to present contact information to the user. The navigation bar at the top of each
page is owned by the navigation controller. The rest of each screen displayed to the user
is managed by a content view controller that presents the information at that specific level
of the data hierarchy. As the user interacts with controls in the interface, those controls tell
the navigation controller to display the next view controller in the sequence or dismiss the
36
current view controller.
Story Board
37
Figure 4.21 Story Board
Often, iOS can automatically instantiate the view controllers in our storyboard at
the moment they are needed. Similarly, the view hierarchy associated with each controller
is automatically loaded when it needs to be displayed. Both view controllers and views are
instantiated with the same attributes we configured in Interface Builder. Because most of
this behavior is automated for, we, it greatly simplifies the work required to use view
controllers in our app.
38
is instantiated. For example, the first connection from a navigation controller to another
scene defines the first view controller pushed onto the navigation stack. This controller is
automatically instantiated when the navigation controller is instantiated.
• A segue represents a visual transition from one scene to another. At runtime, segues
can be triggered by various actions. When a segue is triggered, it causes a new view
controller to be instantiated and transitioned onscreen.
Although a segue is always from one view controller to another, sometimes a third object
can be involved in the process. This object actually triggers the segue. For example, if we
make a connection from a button in the source view controller’s view hierarchy to the
destination view controller, when the user taps the button, the segue is triggered. When a
segue is made directly from the source view controller to the destination view controller,
it usually represents a segue that we intend to trigger programmatically.
Different kinds of segues provide the common transitions needed between two different
view controllers:
• A push segue pushes the destination view controller onto a navigation controller’s
stack.
• A modal segue presents the destination view controller.
• A popover segue displays the destination view controller in a popover.
• A custom segue allows weto design our own transition to display the destination
view controller.
Push Notification
Apple Push Notification service (APNs) is the centerpiece of the remote notifications
feature. It is a robust and highly efficient service for propagating information to iOS (and,
indirectly, watchOS), tvOS, and OS X devices. Each device establishes an accredited and
encrypted IP connection with APNs and receives notifications over this persistent
connection. If a notification for an app arrives when that app is not running, the device
alerts the user that the app has data waiting for it.
39
We provide our own server to generate the remote notifications for our users. This
server, known as the provider, gathers data for our users and decides when a notification
needs to be sent. For each notification, the provider generates the notification payload and
attaches that payload to an HTTP/2 request, which it then sends to APNs using a persistent
and secure channel using the HTTP/2 multiplex protocol. Upon receipt of our request,
APNs handles the delivery of our notification payload to our app on the user’s device.
The device token we provide to the server is analogous to a phone number; it contains
information that enables APNs to locate the device on which our client app is installed.
APNs also uses it to authenticate the routing of a notification. The device token is provided
to us by our client app, which receives the token after registering itself with the remote
notification service.
The notification payload is a JSON dictionary containing the data we want sent to the
device. The payload contains information about how we want to notify the user, such as
using an alert, badge or sound. It can also contain custom data that we define.
The figure 4.23 shows a more realistic depiction of the virtual network APNs makes
possible among providers and devices. The device-facing and provider-facing sides of
APNs both have multiple points of connection; on the provider-facing side, these are called
40
gateways. There are typically multiple providers, each making one or more persistent and
secure connections with APNs through these gateways. And these providers are sending
notifications through APNs to many devices on which their client apps are installed.
Figure 4.23 Pushing remote notifications from multiple providers to multiple devices
Quality of Service
Apple Push Notification service includes a default Quality of Service (QoS)
component that performs a store-and-forward function. If APNs attempts to deliver a
notification but the device is offline, the notification is stored for a limited period of time,
and delivered to the device when it becomes available. Only one recent notification for a
particular app is stored. If multiple notifications are sent while the device is offline, the
new notification causes the prior notification to be discarded. This behavior of keeping
only the newest notification is referred to as coalescing notifications. If the device remains
offline for a long time, any notifications that were being stored for it are discarded.
Security Architecture
To ensure secure communication, APNs regulates the entry points between providers
and devices using two different levels of trust: connection trust and token trust. Connection
trust establishes certainty that APNs is connected to an authorized provider for whom
Apple has agreed to deliver notifications. APNs also uses connection trust with the device
41
to ensure the legitimacy of that device. Connection trust with the device is handled
automatically by APNs but we must take steps to ensure connection trust exists between
our provider and APNs.
Token trust ensures that notifications are routed only between legitimate start and end
points. Token trust involves the use of a device token, which is an opaque identifier
assigned to a specific app on a specific device. Each app instance receives its unique token
when it registers with APNs and must share this token with its provider. Thereafter, the
token must accompany each notification sent by our provider. Providing the token ensures
that the notification is delivered only to the app/device combination for which it is
intended.
Data Base
The database that can be used by apps in iOS (and also used by iOS) is called
SQLite, and it’s a relational database. It is contained in a C-library that is embedded to
the app that is about to use it. Note that it does not consist of a separate service or daemon
running on the background and attached to the app. On the contrary, the app runs it as an
integral part of it. Nowadays, SQLite lives its third version, so it’s also commonly referred
as SQLite 3. SQLite is not as powerful as other DMBSs, such as MySQL or SQL Server,
as it does not include all of their features. However, its greatness lies mostly to these
factors:
• It’s lightweight.
42
• It contains an embedded SQL engine, so almost all of our SQL knowledge can
be applied.
• It works as part of the app itself, and it doesn’t require extra active services.
• It’s very reliable.
• It’s fast.
• It’s fully supported by Apple, as it’s used in both iOS and Mac OS.
• It has continuous support by developers in the whole world and new features are
always added to it.
A good example for this is the relationship between a person and his address as shown
in figure 4.24. A person has typically some properties like first name, last name, birthdate and
much more. An address has properties like street name, street number, etc. But there is also a
relationship between them, a person can have several addresses. In the database this is
achieved by adding a foreign key to the address object. This foreign key points to the primary
key of the person it belongs to. This has also as advantage that when a person is deleted a
warning is given about an associated address. So it becomes possible to also delete the address
if needed.
43
The Core SQLite functions
Let’s first start with a list of the most used SQLite functions and describe their purpose:
• sqlite3_open(): This function creates and opens an empty database with the specified
filename argument. If the database already exists it will only open the database. Upon
return the second argument will contain a handle to the database instance.
• sqlite3_close(): This function should be used to close a previously opened SQLite database
connection. It will free all system resources associated with the database connection.
• sqlite3_prepare_v2(): To execute an SQL statement it first needs to be compiled into byte-
code and that is exactly what this function is doing. It basically transforms an SQL
statement written in a string to an executable piece of code.
• sqlite3_step(): Calling this function will execute a previously prepared SQL statement.
44
2. Name the application "SQLiteTutorial" and make sure to uncheck all options.
45
4. Add a new file to the project. Choose the Cocoa Touch Objective-C template and call
this new file "DataController".
5. Open the header file "DataController.h" and add an import for "sqlite3.h" and a data
member to store a handle to the database:
#import <Foundation/Foundation.h>
#import <sqlite3.h>
@interface DataController : NSObject
{
sqlite3 *databaseHandle;
}
-(void)initDatabase;
@end
6. Now it is time to start adding some entities. Again, choose for the Cocoa Touch
Objective-C template and call the first entity Address. The Address entity will be holding
a street name and a street number.
#import <Foundation/Foundation.h>
@interface Address : NSObject
{
NSString *streetName;
NSNumber *streetNumber;
}
@property (nonatomic,retain) NSString* streetName;
@property (nonatomic,retain) NSNumber* streetNumber;
-(id)initWithStreetName:(NSString*)aStreetName
andStreetNumber:(NSNumber*)streetNumber;
@end
#import "Address.h"
@implementation Address
@synthesize streetName;
@synthesize streetNumber;
46
/ Custom initializer
-(id)initWithStreetName:(NSString*)aStreetName
andStreetNumber:(NSNumber*)aStreetNumber
{
self = [super init];
if(self) {
[Link] = aStreetName;
[Link] = aStreetNumber;
}
return self;
}
#import "Person.h"
@implementation Person
@synthesize firstName;
@synthesize lastName;
@synthesize birthday;
@synthesize address;
// Custom initializer
-(id)initWithFirstName:(NSString*)aFirstName andLastName:(NSString*)aLastName
andBirthday:(NSDate*)aBirthday andAddress:(Address*)anAddress
{
self = [super init];
if(self) {
[Link] = aFirstName;
[Link] = aLastName; [Link] = aBirthday; [Link] = anAddress;
}
return self;
}
48
Now that are basic building blocks are in-place it is time to start working with the SQLite
database.
49
char *error;
if (sqlite3_exec(databaseHandle,
sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
// Create the ADDRESS table with foreign key to the PERSON table
sqlStatement = "CREATE TABLE IF NOT EXISTS ADDRESS (ID INTEGER
PRIMARY KEY AUTOINCREMENT, STREETNAME TEXT, STREETNUMBER
INT, PERSONID INT, FOREIGN KEY(PERSONID) REFERENCES PERSON(ID))";
if (sqlite3_exec(databaseHandle,
sqlStatement, NULL, NULL, &error) == SQLITE_OK)
{
NSLog(@"Database and tables created.");
}
Else
{
NSLog(@"Error: %s", error);
}}
else
{
NSLog(@"Error: %s", error);
}}}}
Let’s highlight some points inside this method:
1. A full path is created that points to [Link] inside the documents folder of the
application. In case when running inside the simulator this will be inside the folder
~Library/Application Support/iPhone Simulator
2. Check if the database file already exists inside the file system.
3. Open a connection to the database and store the databaseHandle for later use.
4. If the database did not exist inside the file system then the tables will be created.
50
6. The table ADDRESS is also created with an auto-incrementing primary key and a
foreign key constraint set to the ID of the PERSON table and will be called
PERSONID.
It is also important to close the database connection once the DataController gets released.
To do this simply override the "dealloc" method of the class DataController:
- (void)dealloc {
sqlite3_close(databaseHandle);
To verify this piece of code update the method "viewDidLoad" from the file
"ViewController.m" so that it looks like:
- (void)viewDidLoad
[super viewDidLoad];
[dataController initDatabase];
[dataController release];
Next part to implement is a method to insert a Person and his associated Address inside
the database. To do so a new method called "insertPerson" needs to be created inside the
DataController:
-(void)insertPerson:(Person*)person
{
51
// Create insert statement for the person
NSString *insertStatement = [NSString stringWithFormat:@"INSERT INTO PERSON
(FIRSTNAME, LASTNAME, BIRTHDAY) VALUES
(\"%@\", \"%@\", \"%@\")", [Link], [Link], [Link]];
char *error;
if ( sqlite3_exec(databaseHandle, [insertStatement UTF8String], NULL, NULL, &error)
==SQLITE_OK)
{
int personID = sqlite3_last_insert_rowid(databaseHandle);
// Create insert statement for the address
insertStatement = [NSString stringWithFormat:@"INSERT INTO ADDRESS
(STREETNAME, STREETNUMBER, PERSONID) VALUES
(\"%@\", \"%@\", \"%d\")", [Link], [Link],
personID];
if ( sqlite3_exec(databaseHandle, [insertStatement
UTF8String], NULL, NULL, &error) ==SQLITE_OK)
{
NSLog(@"Person inserted.");
}
else{
NSLog(@"Error: %s", error);
}}
Else
{
NSLog(@"Error: %s", error);
}}
Lets discuss the previous code snippet:
1. Create an insert statement for the person object.
2. Execute the insert statement for the person by calling "sqlite3_exec".
3. Get the ID of the last inserted row by calling "sqlite3_last_insert_rowid". This ID
needs to be pasted as the foreign key for the address object.
4. Create the insert statement for the address object. Note that the foreign key is also
passed in.
52
5. Execute the insert statement for the address by calling "sqlite3_exec".
Again it is possible to test the new code by updating the method "viewDidLoad":
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
// Cleanup
[dateFormatter release];
[address release];
[person release];
[DataController release];
Testing the result of this action can be done again from the command line with sqlite3
Terminal command:
1|Infinite Loop|1|
53
Retrieving values from the SQLite database
Now it is time to programmatically retrieve values from the database. This can be done by
using the "sqlite3_step" function. The DataController implementation file needs to be
updated with a method called "getAddressByPersonID" and "getPersons". The method
"getAddressByPersonID" is a helper method to get an address associated with a person.
The method "getPersons" returns an array of all persons inside the database.
-(NSArray*)getPersons
sqlite3_stmt *statement;
54
[Link] = @"yyyy-MM-dd HH:mm:ss Z";
(char*)sqlite3_column_text(statement, 3)];
[dateFormatter release];
andLastName:[NSString stringWithUTF8String:
(char*)sqlite3_column_text(statement, 2)]
andBirthday:birthday andAddress:address];
[persons addObject:person];
[person release];
sqlite3_finalize(statement);
We can log in using our existing Apple ID or create an Apple ID. The Apple Developer
Registration guides us through the necessary steps.
55
2. Register the Unique Device Identifier (UDID) of the device.
This step is applicable only if we are deploying our application to an iOS device and not
the Apple App Store. If we want to deploy our application on several iOS devices, register
the UDID of each device.
56
• Click Request Certificate and browse to the CSR file that we generated and saved on
our computer (step 3).
• Select the CSR file and click Submit.
• On the Certificates page, click Download.
• Save the downloaded file (*.distribution_identity.cer).
• 1 Convert the iOS developer certificate or the iOS distribution certificate to a P12 file
format (*.p12).
7. Generate the Application ID by following these steps:
• Log in to the iOS Provisioning Portal using our Apple ID.
• Go to the App IDs page, and click New App ID.
• In the Manage tab, enter a description for our application, generate a new Bundle Seed
ID, and enter a Bundle Identifier.
• Every application has a unique Application ID, which wespecify in the application
descriptor XML file. An Application ID consists of a ten-character "Bundle Seed ID"
that Apple provides and a "Bundle Identifier" suffix that wespecify. The Bundle
Identifier we specify must match the application ID in the application descriptor file.
For example, if our Application ID is [Link].*, the ID in the application
descriptor file must start with [Link].
• Generate a Developer Provisioning Profile file or a Distribution Provisioning Profile
File (*.mobileprovision).
8. Generate a Developer Provisioning Profile
• Log in to the iOS Provisioning Portal using our Apple ID.
• Go to Certificate > Provisioning, and click New Profile.
• Enter a profile name, select the iOS developer certificate, the App ID, and the UDIDs
on which wewant to install the application.
• Click Submit.
• Download the generated Developer Provisioning Profile file (*.mobileprovision)and
save it on our computer.
9. Generate a Distribution Provisioning Profile
• Log in to the iOS Provisioning Portal using our Apple ID. Go to Certificate > Provisioning,
and click New Profile.
57
• Enter a profile name, select the iOS distribution certificate and the App ID. If we want to
test the application before deployment, specify the UDIDs of the devices on which we
want to test.
• Click Submit.
• Download the generated Provisioning Profile file (*.mobileprovision)and save it on our
computer.
• To run, debug, or install an application for testing on an iOS device, we select the following
files in the Run/Debug Configurations dialog box:
• iOS developer certificate in P12 format (step 5)
• Application descriptor XML file that contains the Application ID (step 6)
• Developer Provisioning Profile (step 7)
For more information, see Debug an application on an Apple iOS deviceand Install an
application on an Apple iOS device.
To deploy an application to the Apple App Store, select the Package Type in the
Export Release Build dialog box as Final Release Package For Apple App Store, and
select the following files:
The App Store review process is a black box for the most part, that doesn't mean that
we can't prepare ourself and our application for Apple's review process. Apple provides
58
guidelines to help we stay within the sometimes-invisible boundaries of what is and isn't
allowed in the App Store.
Testing
An application isn't necessarily ready when we've written the last line of code or
implemented the final feature of the application's specification. The family of iOS devices
has grown substantially over the past years and it is important to test our application on as
many iOS devices as we can lay our hands on. The iOS Simulator is a great tool, but it runs
on our Mac, which has more memory and processing power than the phone in our pocket.
Apple's Review Process isn't airtight, but it is very capable of identifying problems that might
affect our application's user experience. If our application crashes from time to time or it
becomes slow after ten minutes of use, then we have some work to do before submitting it to
the App Store. Even if Apple's review team doesn't spot the problem, our users will. If the
people using our application are not pleased, they will leave bad reviews on the App Store,
which may harm sales or inhibit downloads.
• doesn't crash.
• only uses artwork that we have the copyright of or we have permission to use.
1. App ID
Every application needs an App ID or application identifier. There are two types of
application identifiers, (1) an explicit App ID and (2) a wildcard App ID. A wildcard
App ID can be used for building and installing multiple applications. Despite the
convenience of a wildcard App ID, an explicit App ID is required if our application uses
59
iCloud or makes use of other iOS features, such as Game Center, Apple Push
Notifications, or In App Purchase.
2. Distribution Certificate
To submit an application to the App Store, we need to create an iOS provisioning profile
for distribution. To create such a provisioning profile, we first need to create a distribution
certificate. The process for creating a distribution certificate is very similar to creating a
development certificate. If we have tested our application on a physical device, then we
are probably already familiar with the creation of a development certificate.
3. Provisioning Profile
Once we've created an App ID and a distribution certificate, we can create an iOS
provisioning profile for distributing our application through the App Store. Keep in mind
that we cannot use the same provisioning profile that we use for ad hoc distribution. We
need to create a separate provisioning profile for App Store distribution. If we use a
wildcard App ID for our project, then we can use the same provisioning profile for multiple
applications.
4. Build Settings
With the App ID, distribution certificate, and provisioning profile in place, it is time to
configure our target's build settings in Xcode. This means selecting the target from the list
of targets in Xcode's Project Navigator, opening the Build Settings tab at the top, and
updating the settings in the Code Signing section to match the distribution provisioning
profile we created earlier. Newly added provisioning profiles are sometimes not
immediately visible in the Code Signing section of the build settings. Quitting and
relaunching Xcode remedies this issue.
5. Deployment Target
Each target in an Xcode project, has a deployment target, which indicates the minimum
version of the operating system that the application can run on. It is up to we to set the
deployment target, but keep in mind that modifying the deployment target is not something
we can do without consequences once our application is in the App Store. If we increase
the deployment target for an update of our application, then users who already purchased
our application but don't meet the new deployment target, cannot run the update.
60
Assets
1. Icons
We need to make sure that our application ships with the correct sizes of the artwork.
2. Screenshots
Each application can have up to five screenshots and we must provide at least one. If we
are developing a universal application, then we need to provide separate screenshots for
iPhone/iPod Touch and iPad/iPad Mini. In addition, we can optionally include separate
screenshots for the 3.5" and the 4" screen sizes of the iPhone/iPod Touch. This is quite a
bit of work and we want to make sure that the screenshots show our application from its
best side.
3. Metadata
Before we submit our application, it is a good idea to have our application's metadata at
hand. This includes (1) our application's name, (2) the version number, (3) the primary
(and an optional secondary) category, (4) a concise description, (5) keywords, and (6) a
support URL.
4. Submission Preparation
1. The submission process has become much easier since the release of Xcode 4. We can
now validate and submit an application using Xcode, for example. First, however, we
need to create our application in iTunes Connect.
2. The App Name, which needs to be unique, is the name of our application as it will
appear in the App Store. This can be different than the name that is displayed below our
application icon on the home screen, but it is recommended to choose the same name.
61
3. The SKU Number is a unique string that identifies our application. I usually use the
application's bundle identifier. The last piece of information is the Bundle ID of our
application. This means selecting the (wildcard or explicit) App ID that we created earlier
from the drop-down menu.
5. Once our application's metadata is submitted, we will be presented with a summary of our
application. Under Versions, we should see the version that we submitted a moment ago.
6. To submit our application, we need to create an archive of our application. We can only
create an archive by building our application on a physical device. Select the archive from
the list and click the Distribute button on the right. From the options we are presented
with, select Submit to the iOS App Store. After entering our iOS developer account
credentials and selecting the Application and Code Signing Identity, the application
binary is uploaded to Apple's servers. During this process, our application is also validated.
If an error occurs during the validation, the submission process will fail. The validation
process is very useful as it will tell we if there is something wrong with our application
binary that would otherwise result in a rejection by the App Store review team.
62
SCHOOL OF COMPUTING
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
Unit 5
Introduction to Windows Phone 8, Application Life cycle, UI Designing and events, Building,
Files and Storage, Network Communication, Push Notification, Background Agents, Maps and
Locations, Data Access and storage, Introduction to Silverlight and XAML, Running and
Debugging the App, Deploying and Publishing
1
Introduction to windows phone 8
Update 1 (or GDR1), which added some improvements in Internet Explorer, Wi-Fi
connectivity, and messaging experience
2
Update 2 (or GDR2), which improved support for Google accounts, Xbox Music, and
Skype, added FM radio support, and expanded the availability of the Data Sense
application to keep track of the data traffic
Update 3 (or GDR3), which added support for a new resolution (1080p), driving mode,
screen lock orientation, and better storage management, and improved the Bluetooth and
Wi-Fi stack
Windows Phone can run on a wide range of devices, with different form factors and
hardware capabilities. However, Microsoft has defined a set of hardware guidelines that all
manufacturers need to follow to build a Windows Phone device. In addition, vendors can’t
customize the user interface or the operating system; all the phones, regardless of the producer,
offer the same familiar user experience.
This way, Windows Phone can take the best from both worlds: a wide range of devices
means more opportunities, because Windows Phone can run well on cheap and small devices in
the same way it works well on high-resolution, powerful phones. A more controlled hardware,
instead, makes the lives of developers much easier, because they can always count on features
like sensors or GPS.
3
four supported resolutions: WVGA (480 × 800), WXGA (768 × 1280), 720p(720 ×
1280), and 1080p (1080 × 1920)
three hardware buttons: Back, Start, and Search
The Windows Runtime is the new API layer that Microsoft introduced in Windows 8,
and it’s the foundation of a new and more modern approach to developing applications. In fact,
unlike the .NET framework, it’s a native layer, which means better performance. Plus, it supports
a wide range of APIs that cover many of the new scenarios that have been introduced in recent
years: geolocation, movement sensors, NFC, and much more. In the end, it’s well suited for
asynchronous and multi-threading scenarios that are one of the key requirements of mobile
applications; the user interface needs to be always responsive, no matter which operation the
application is performing.
Under the hood of the operating system, Microsoft has introduced the Windows Phone
Runtime. Compared to the original Windows Runtime, it lacks some features (specifically, all
the APIs that don’t make much sense on a phone, like printing APIs), but it adds several new
ones specific to the platform (like hub integration, contacts and appointments access, etc.).
The XAML stack has been ported directly from Windows Phone 7 instead of from
Windows 8. This means that the XAML is still managed and not native, but it's
completely aligned with the previous one so that, for example, features like behaviors, for
which support has been added only in Windows 8.1, are still available). This way, you’ll
be able to reuse all the XAML written for Windows Phone 7 applications without having
to change it or fix it.
Thanks to a feature called quirks mode, applications written for Windows Phone 7 are
able to run on Windows Phone 8 devices without having to apply any change in most
cases. This mode is able to translate Windows Phone 7 API calls to the related Windows
Runtime ones.
4
The Windows Phone Runtime includes a layer called .NET for Windows Phone, which
is the subset of APIs that were available in Windows Phone 7. Thanks to this layer, you’ll
be able to use the old APIs in a Windows Phone 8 application, even if they’ve been
replaced by new APIs in the Windows Runtime. This way, you’ll be able to migrate your
old applications to the new platform without having to rewrite all the code.
Like the full Windows Runtime, Windows Phone 8 has added support for C++ as a
programming language, while the WinJS layer, which is a library that allows developers to
create Windows Store apps using HTML and JavaScript, is missing. If you want to develop
Windows Phone applications using web technologies, you’ll have to rely on
the WebBrowser control (which embeds a web view in the application) and make use of
features provided by frameworks like PhoneGap.
The official platform to develop Windows Phone applications is Visual Studio 2012,
although support has also been added to the Visual Studio 2013 commercial versions. The major
difference is that while Visual Studio 2012 still allows you to open and create Windows Phone 7
projects, Visual Studio 2013 can only be used to develop Windows Phone 8 applications.
There are no differences between the two versions when we talk about Windows Phone
development: since the SDK is the same, you’ll get the same features in both environments, so
we’ll use Visual Studio 2012 as a reference for this series.
To start, you’ll need to download the Windows Phone 8 SDK from the official developer
portal. This download is suitable for both new developers and Microsoft developers who already
have a commercial version of Visual Studio 2012. If you don’t already have Visual Studio
installed, the setup will install the free Express version; otherwise, it will simply install the SDK
and the emulator and add them to your existing Visual Studio installation.
The setup will also install Blend for Windows Phone, a tool made by Microsoft
specifically for designers. It’s a XAML visual editor that makes it easier to create a user interface
for a Windows Phone application. If you’re a developer, you’ll probably spend most of the time
5
manually writing XAML in the Visual Studio editor, but it can be a valid companion when it
comes to more complex things like creating animations or managing the visual states of a
control.
To install the Windows Phone 8 SDK you’ll need a computer with Windows 8
Pro orWindows 8 Enterprise 64-bit. This is required since the emulator is based on Hyper-V,
which is the Microsoft virtualization technology that is available only in professional versions of
Windows. In addition, there’s a hardware requirement: your CPU needs to support the Second
Level Address Translation (SLAT), which is a CPU feature needed for Hyper-V to properly run.
If you have a newer computer, you don’t have to worry; basically all architectures from Intel i5
and further support it. Otherwise, you’ll still be able to install and the use the SDK, but you’ll
need a real device for testing and debugging.
Testing and debugging a Windows Phone app on a device before submitting it to the
Windows Phone Store is a requirement; only on a real phone will you be able to test the true
performance of the application. During daily development, using the device can slow you down.
This is when the emulator is useful, especially because you’ll easily be able to test different
conditions (like different resolutions, the loss of connectivity, etc.).
The emulator is a virtual machine powered by Hyper-V that is able to interact with the
hardware of your computer. If you have a touch monitor, you can simulate the phone touch
screen; if you have a microphone, you can simulate the phone microphone, etc. In addition, the
emulator comes with a set of additional tools that are helpful for testing some scenarios that
would require a physical device, like using the accelerometer or the GPS sensor.
6
1. Windows application life cycle
The following image illustrates the lifecycle of a Windows Phone application. In this
diagram, the circles are application states. The rectangles show either application- or page-level
events where applications should manage their state.
A user can launch a new instance of your app by selecting it from the installed
applications list or from a Tile on Start in addition to other means, such as tapping on a toast
7
notification associated with the app or selecting the app from the Photos Extras menu. When
your app is launched this way, it should present a user interface that makes it clear to the user
that a new instance the app was launched. It’s ok to provide context about the user’s previous
experience with the app, such as a list of recent documents the user viewed, but it shouldn’t
appear as though the user is returning to a previously running instance of the app.
When a new instance of your app is launched, the Launching event is raised. To help
ensure that your app loads quickly, you should execute as little code as possible in the handler
for this event. In particular, avoid resource-intensive tasks like file and network operations. You
should perform these tasks on a background thread after your app has loaded for the best user
experience.
2.2 Running
After being launched, an app is Running. It continues to run until the user navigates
forward, away from the app, or backwards past the app’s first page. Windows Phone apps
shouldn’t provide a mechanism for the user to quit or exit. Apps also leave the Running state
when the phone’s lock screen engages unless you have disabled application idle detection. For
more information, see Idle detection for Windows Phone 8.
8
2.5 Dormant
When the user navigates forward, away from an app, after the Deactivated event is
raised, the operating system will attempt to put the app into a dormant state. In this state, all of
the application’s threads are stopped and no processing takes place, but the application remains
intact in memory. If the app is reactivated from the dormant, it doesn’t need to do anything to re-
establish state, because it has been preserved.
If new apps are launched after an app has been made dormant, and these applications
requires more memory than is available to provide a good user experience, the operating system
will begin to tombstone dormant applications to free up memory.
2.6 Tombstoned
A tombstoned app has been terminated, but the operating system preserves information
about its navigation state and also preserves the state dictionaries the app populated
during Deactivated. The device will maintain tombstoning information for up to five apps at a
time. If an app is tombstoned and the user navigates back to the application, it will be relaunched
and the application can use the preserved data to restore state.
9
2. UI Design Guidelines for Windows Phone 8
3.1 App bar and command bar
Command bars (also called "app bars") provide users with easy access to your app's most
common tasks, and can be used to show commands or options that are specific to the user's
context, such as a photo selection or drawing mode. They can also be used for navigation among
app pages or between app sections. Command bars can be used with any navigation pattern.
Command Bar
The "see more" [•••] button is shown on the right of the bar. Pressing the "see more" [•••]
button has 2 effects: it reveals the labels on the primary command buttons, and it opens
the overflow menu if any secondary commands are present. In the newest SDK, the
button will not be visible when no secondary commands and no hidden labels are
present. OverflowButtonVisibility property allows apps to change this default auto-hide
behavior.
The content area is aligned to the left side of the bar. It is shown if the Content property is
populated.
The primary command area is aligned to the right side of the bar, next to the "see more"
[•••] button. It is shown if the PrimaryCommands property is populated.
The overflow menu is shown only when the command bar is open and
the SecondaryCommands property is populated. The new dynamic overflow behavior
will automatically move primary commands into the SecondaryCommands area when
space is limited.
10
3.2 Buttons
[Link] = "Submit";
[Link] += SubmitButton_Click;
await [Link]();
Button
A check box is used to select or deselect action items. It can be used for a single item or for a
list of multiple items that a user can choose from. The control has three selection states:
unselected, selected, and indeterminate. Use the indeterminate state when a collection of sub-
choices have both unselected and selected states.
This XAML creates a single check box that is used to agree to terms of service before a form
can be submitted.
Check Box
3.4 Calendar view
A calendar view lets a user view and interact with a calendar that they can navigate by month,
year, or decade. A user can select a single date or a range of dates. It doesn't have a picker
surface and the calendar is always visible.
12
The calendar view is made up of 3 separate views: the month view, year view, and decade
view. By default, it starts with the month view open.
<CalendarView/>
Calender View
[Link]([Link]);
[Link](new DateTime(1977, 1, 5));
Customizing the calendar view's appearance
13
Properties of Calender View
The date picker gives you a standardized way to let users pick a localized date value using
touch, mouse, or keyboard input.
Date Picker
3.6 Time picker
The time picker gives you a standardized way to let users pick a time value using touch, mouse,
or keyboard input.
Or
14
Time Picker
3.7 Dialogs
Dialogs is transient UI elements that appear when something happens that requires
notification, approval, or additional information from the user.
Dialog Control
Hyperlinks navigate the user to another part of the app, to another app, or launch a specific
uniform resource identifier (URI) using a separate browser app. There are two ways that you
can add a hyperlink to a XAML app: the Hyperlink text element
and HyperlinkButton control.
This example shows how to use a Hyperlink text element inside of a TextBlock.
15
Sample Code
The hyperlink appears inline and flows with the surrounding text:
Hyperlink
3.9 Images
To display an image, you can use either the Image object. An Image object renders an
image.
16
image
3.10 Radio buttons
Radio buttons let users select one option from two or more choices. Each option is represented
by one radio button; a user can select only one radio button in a radio button group.
Sample Code
private void BGRadioButton_Checked(object sender, RoutedEventArgs e)
{
RadioButton rb = sender as RadioButton;
17
break; case
"Blue":
[Link] = new SolidColorBrush([Link]); break;
case "White":
[Link] = new SolidColorBrush([Link]);
break;
}
}
}
private void BorderRadioButton_Checked(object sender, RoutedEventArgs e)
{
RadioButton rb = sender as RadioButton;
18
Radio Buttons
3.11 Text box
The TextBox control lets a user type text into an app. It's typically used to capture a single line
of text, but can be configured to capture multiple lines of text. The text displays on the screen
in a simple, uniform, plaintext format.
Here's the XAML for a simple text box with a header and placeholder text.
or
[Link] = 500;
[Link] = "Notes";
[Link](textBox);
Text Box
A password box is a text input box that conceals the characters typed into it for the purpose of
privacy. A password box looks like a text box, except that it renders placeholder characters in
place of the text that has been entered. You can configure the placeholder character.
Here's the XAML for a password box control that demonstrates the default look of the
PasswordBox.
<StackPanel>
19
<PasswordBox x:Name="passwordBox" Width="200" MaxLength="16"
PasswordChanged="passwordBox_PasswordChanged"/>
</StackPanel>
Here's the result when this code runs and the user enters "Password".
You can change the character used to mask the password by setting
the PasswordChar property. Here, the default bullet is replaced with an asterisk.
Password Character
Headers and placeholder text
Use an AutoSuggestBox to provide a list of suggestions for a user to select from as they
type.
to make the AutoSuggestBox look like a typical search box, add a ‘find’ icon, like this.
<AutoSuggestBox QueryIcon="Find"/>
AutoSuggest Box
3.14 Labels
21
Label
3.15 Toggle switches
22
The toggle switch represents a physical switch that allows users to turn things on or off. Use
ToggleSwitch controls to present users with exactly two mutually exclusive options (like
on/off), where choosing an option results in an immediate action.
[Link] = "WiFi";
[Link](wiFiToggle);
Toggle switch
3.16 Tooltips
A tooltip is a short description that is linked to another control or object. Tooltips help users
understand unfamiliar objects that aren't described directly in the UI. They display automatically
when the user moves focus to, presses and holds, or hovers the mouse pointer over a control.
The tooltip disappears after a few seconds, or when the user moves the finger, pointer or
keyboard/gamepad focus.
Tooltips
23
3. Events
An event is a message sent by an object to signal the occurrence of an action. The action
could be caused by user interaction, such as touching the screen, or it could be triggered by the
internal logic of a class. The object that raises the event is called the event sender. The object that
captures the event and responds to it is called the event receiver. Basically the purpose of events
is to communicate time-specific, relatively lightweight information from an object at run time,
and potentially to deliver that information to other objects in the app.
Because the UI for a typical Windows Phone-based app is defined in markup (XAML),
some of the principles of connecting UI events from markup elements to a runtime code entity
are similar to other Web technologies, such as [Link], or working with an HTML DOM. In
Windows Phone the code that provides the runtime logic for a XAML-defined UI is often
referred to as code-behind or the code-behind file. In the Visual Studio solution views, this
relationship is shown graphically, with the code-behind file being a dependent and nested file
versus the XAML page it refers to.
Generally, you define the UI for your Windows Phone-based app by generating XAML.
This XAML can be the output from a designer such as Blend for Visual Studio or from a design
surface in a larger IDE such as Windows Phone. The XAML can also be written out in a
plaintext editor or a third-party XAML editor. As part of generating that XAML, you can wire
event handlers for individual UI elements at the same time that you define all the other attributes
that describe that UI element.
If you are using Windows Phone, you can use design features that make it very simple to wire
event handlers from XAML and then define them in code-behind. This includes providing an
automatic naming scheme for the handlers.
Event handlers in the partial class are written as methods, based on the CLR delegates
that are used by that particular event. Your event handler methods can be public, or they can
have a private access level. Private access works because the handler and instance created by the
XAML are ultimately joined by code generation. The general recommendation is to not make
your event handler methods public in the class.
24
4.4 The sender parameter and event data
Any handler you write for a managed Windows Phone event can access two values that
are available as input for each case where your handler is invoked. The first such value is sender,
which is a reference to the object where the handler is attached. The sender parameter is typed as
the base Object type. A common technique in Windows Phone event handling is to cast sender to
a more precise type. This technique is useful if you expect to check or change state on
thesender object itself. Based on your own app design, you expect a type that is safe to
cast sender to, based on where the handler is attached or other design specifics.
The second value is event data, which generally appears in signatures as the e parameter.
Per the CLR event model, all events send some kind of event data, with that data captured as an
instance of a class that inherits EventArgs (or isEventArgs itself). You can discover which
properties for event data are available by looking at the e parameter of the delegate that is
assigned for the specific event you are handling, and then using Intellisense in Visual Studio or
the .NET Framework Class Library for Windows Phone. Some Windows Phone events use
the EventHandler<TEventArgs>delegate or other generic handler types. In most cases, the event
definitions constrains the generic with a specific EventArgs derived event data class. You should
then write the handler method as if it took that EventArgs derived event data class directly as the
second parameter.
For some events, the event data in the EventArgs derived class is as important as
knowing that the event was raised. This is especially true of the input events. For keyboard
events, key presses on the keyboard raise the same KeyUp andKeyDown events. In order to
25
determine which key was pressed, you must access the KeyEventArgs that is available to the
event handler.
XAML is not the only way to assign an event handler to an object. To add event handlers
to any given object in managed code, including to objects that are not even usable in XAML, you
can use the CLR language-specific syntax for adding event [Link] C#, the syntax is to use
the += operator. You instantiate the handler by declaring a new delegate that uses the event
handler method name.
If you are using code to add event handlers to objects that appear in the run-time UI, a
common practice for Windows Phone is to add such handlers in response to an object lifetime
event or callback, such as Loaded orOnApplyTemplate, so that the event handlers on the relevant
object are ready for user-initiated events at run time.
The other option for Visual Basic syntax is to use the Handles keyword on event
handlers. This technique is appropriate for cases where handlers are expected to exist on objects
at load time and persist throughout the object lifetime. Using Handles on an object that is
defined in XAML requires that you provide a Name / x:Name. This name becomes the instance
qualifier that is needed for the [Link] part of the Handles syntax. In this case you do not
need an object lifetime-based event handler to initiate attaching the other event handlers;
the Handles connections are created when you compile your XAML page.
VB
KeyDown
KeyUp
GotFocus
LostFocus
26
MouseLeftButtonDown
MouseLeftButtonUp
MouseMove
BindingValidationError
A routed event is an event that is potentially passed on (routed) from a child object to
each of its successive parent objects in the object tree. The object tree in question is
approximated by the XAML structure of your UI, with the root of that tree being the root
element in XAML. The true object tree might vary somewhat from the XAML because the
object tree does not include XAML language features such as property element tags.
When an event bubbles up an event route, sender is no longer the same object as the
event-raising object. Instead,sender is the object where the handler that is being invoked is
attached. In many cases, sender is not the object of interest, and you are instead interested in
knowing information such as object held focus when a keyboard key was pressed. In such a case,
the value of the OriginalSource property is the object of interest.
At all points on the route, OriginalSource reports the original object that raised the event,
instead of where the handler is attached. For an example scenario where this is useful, consider
an app where you want certain key combinations to be "hot keys" or accelerators, regardless of
which control currently holds keyboard focus and initiated the event. In terms of the object tree,
the focused object might be nested within some items list in a list box, or could be one of
hundreds of objects in the overall UI.
Setting the Handled property to true influences the event system in Windows Phone.
When you set the value to truein event data, the routing stops for most event handlers; the event
does not continue along the route to notify other attached handlers of that particular event case.
What "handled" as an action means in the context of the event and how your app responds is up
to you. However, you should keep in mind the behavior of the Windows Phone event system if
you set Handled in your event handlers.
Specific existing Windows Phone controls sometimes use this Handled concept for input
events internally. This can give the appearance from user code that an input event never occurs.
27
For example, the Button class includes logic that deliberately handles the general input
event MouseLeftButtonDown. Reference topics for specific control classes in the .NET
Framework Library often note the event handling behavior implemented by the class. In some
cases, the behavior can be changed or appended in subclasses by overriding OnEvent methods.
For example, you can change how your TextBox derived class reacts to key input by
overriding [Link].
Earlier it was stated that setting Handled to true prevented most handlers from acting.
The API AddHandler provides a technique where you can attach a handler that will always be
invoked for the route, even if some other handler earlier in the route has set Handled to true.
This technique is useful if a control you are using has handled the event in its internal
compositing or for control-specific logic but you still want to respond to it on a control instance,
or higher in the route. However, this technique should be used with caution because it can
contradict the purpose of Handled and possibly violate a control's intended usage or object
model.
Windows Phone enforces that certain operations are only permitted in the context of a
handler that handles a user-initiated event. The following is a list of such operations:
28
DATA ACCESS AND STORAGE
Local Storage
The Internet plays an important role in mobile applications. Most Windows Phone
applications available in the Store make use of the network connection offered by every device.
However, relying only on the network connection can be a mistake; users can find themselves in
situations where no connection is available. In addition, data plans are often limited, so the fewer
network operations we do, the better the user experience is.
Windows Phone offers a special way to store local data called isolated storage. It works
like a regular file system, so you can create folders and files as on a computer hard drive. The
difference is that the storage is isolated—only your applications can use it. No other applications
can access your storage, and users are not able to see it when they connect their phone to the
computer. Moreover, as a security measure, the isolated storage is the only storage that the
application can use. You’re not allowed to access the operating system folders or write data in
the application’s folder.
Local storage is one of the features which offers duplicated APIs—the old Silverlight
ones based on the IsolatedStorageFile class and the new Windows Runtime ones based on the
LocalFolder class. As mentioned in the beginning of the series, we’re going to focus on the
Windows Runtime APIs.
This class exposes different asynchronous methods to interact with the current folder, such as:
{
await
[Link]
[Link](“myF
older”);
The starting point to manipulate a file is the StorageFolder class we’ve previously discussed,
since it offers methods to open an existing file ( GetFileAsync() ) or to create a new one in the
current folder ( CreateFileAsync() ).
Let’s examine the two most common operations: writing content to a file and reading content
from a file.
30
private async void OnCreateFileClicked(object sender, RoutedEventArgs e)
You can also pass the optional parameter CreationCollisionOption to the method to define the
behavior to use in case a file with the same name already exists. In the previous sample,
the ReplaceExisting value is used to overwrite the existing file.
Now that you have a file reference thanks to the StorageFile object, you are able to
work with it using the OpenAsync() method. This method returns the file stream, which you
can use to write and read content.
The following sample shows how to write text inside the file:
[Link](“[Link]”,
[Link]([Link]);
[Link]
tring(“Sampl
31
e text”);
await
[Link]
sync(); }
The key is the DataWriter class, which is a Windows Runtime class that can be used to
easily write data to a file. We simply have to create a new DataWriter object, passing as a
parameter the output stream of the file we get using the GetOuputStreamAt() method on the
stream returned by the OpenAsync() method.
The DataWriter class offers many methods to write different data types,
like WriteDouble() for decimal numbers, WriteDateTime() for dates, and WriteBytes() for
binary data. In the sample we write text using the WriteString() method, and then we call
the StoreAsync() and FlushAsync() methods to finalize the writing operation.
{
StorageFile file = await
[Link]("[Link]");
[Link]([Link]);
[Link](bytesLoaded);
[Link](readString);
Manage Settings
One common scenario in mobile development is the need to store
settings. Many applications offer a Settings page where users can
customize different options.
Note: The IsolatedStorageSettings class is part of the old storage APIs; the Windows
Runtime
offers a new API to manage settings but, unfortunately, it isn’t available in Windows
Phone.
In the following sample, you can see two event handlers: the first one
saves an object in the settings, while the second one retrieves it.
{
33
IsolatedStorageSettings settings =
[Link];
[Link]("name", "Matteo");
[Link]();
{
IsolatedStorageSettings settings =
[Link]; if
([Link]("name"))
{
[Link](settings["name"].ToString());
The only thing to highlight is the Save() method, which you need to call every time you want to
34
persist the changes you’ve made. Except for this, it works like a regular Dictionary collection.
The best way to view an application’s local storage is by using a third-party tool available
on CodePlex called Windows Phone Power Tools, which offers a visual interface for exploring
an application’s local storage.
The tool is easy to use. After you’ve installed it, you’ll be able to connect to a device or
to one of the available emulators. Then, in the Isolated Storage section, you’ll see a list of all
the applications that have been side-loaded from Visual Studio. Each one will be identified by its
application ID (which is a GUID). Like a regular file explorer, you can expand the tree structure
and analyze the storage’s content. You’ll be able to save files from the device to your PC, copy
files from your PC to the application storage, and even delete items.
Storing Techniques
public string
Name { get;
set; } public
string
Surname {
get; set; }
We assume that you will have a collection of Person objects, which represents your local data:
{
new Person
{
"Pagani"
},
36
new Person
};
Serialization
To serialize our application’s data we’re going to use the local storage APIs we learned about in
the previous section. We’ll use the method again, CreateFile()
as shown in the
following sample:
[Link]("[Link]");
[Link]([Link]);
[Link]
bject(stream,
people); await
[Link]
nc();
37
}
<ArrayOfPerson xmlns:i="[Link]
xmlns="[Link]
<Person>
<Name>Matteo</Name>
<Surname>Pagani</Surname>
</Person>
<Person>
<Name>John</Name>
<Surname>Doe</Surname>
</Person>
</ArrayOfPerson>
38
Deserialization
The deserialization process is very similar and involves, again, the storage APIs to read
the file’s content and the DataContractSerializer class. The following sample shows how to
deserialize the data we serialized in the previous section:
[Link]("[Link]");
DataContractSerializer(typeof(List<Person>));
39
Using Databases: SQL CE
SQL CE is the database solution that was introduced in Windows Phone 7.5. It’s
a stand- alone database, which means that data is stored in a single file in the storage
without needing a DBMS to manage all the operations.
Windows Phone uses SQL CE 3.5 (the latest release at this time is 4.0, but it is
not supported) and doesn’t support SQL query execution. Every operation is made using
LINQ to SQL, which is one of the first of Microsoft’s ORM solutions.
The approach used by SQL CE on Windows Phone is called code first. The
database is created the first time the data is needed, according to the entities definition
that you’re going to store in tables. Another solution is to include an already existing
SQL CE file in your Visual Studio project. In this case, you’ll only be able to work with
it in read-only mode.
The first step is to create the entities that you’ll need to store in your database.
Each entity will be mapped to a specific [Link] definition is made using attributes,
which are part
of the [Link] namespace. Each property is decorated with an
attribute,
which will be used to translate it into a column. In the following sample we adapt the
familiar Person class to be stored in a table:
[Table]
[Column]
The entire entity is marked with the Table attribute, while every property is marked with
the Column attribute. Attributes can be customized with some properties, like:
The DataContext class contains the connection string’s definition (which is the path
where the database is stored) and all the tables that are included in the database. In the
following sample,
you can see a DataContext definition that includes the Person table we’ve
previously defined:
isostore:/ means that the file is stored in the local storage. In the previous
sample, the
database’s file name is [Link] and it’s stored in the storage’s root.
appdata:/ means that the file is stored in the Visual Studio project
instead. In this case,
you’re forced to set the File Mode attribute to Read Only .
As soon as the data is needed, you’ll need to create the database if it doesn’t exist
yet. For
this purpose, the DataContext class exposes two methods:
In the following sample, you can see a typical database initialization that is executed every time
the application starts:
if (![Link]())
[Link]();
All the operations are made using the Table<T> object that we’ve declared in
the DataContext definition. It supports standard LINQ operations, so you can query the data
using methods like Where() , FirstOrDefault() , Select() , and OrderBy() .
In the following sample, you can see how we retrieve all the Person objects in the table whose
name is Matteo:
}
43
}
The returned result can be used not only for display purposes, but also for editing. To update the
item in the database, you can change the values of the returned object by calling
the SubmitChanges() method exposed by the DataContext class.
To add new items to the table, the Table<T> class offers two
methods: InsertOnSubmit() and InsertAllOnSubmit() . The first method can be used to insert a
single object, while the second one adds multiple items in one operation (in fact, it accepts a
collection as a parameter).
Name = "Matteo",
Surname = "Pagani" };
[Link](person);
[Link]();
Please note again the SubmitChanges() method: it’s important to call it every
time you modify
44
the table (by adding a new item or editing or deleting an already existing one),
otherwise changes won’t be saved.
{
List<Person> persons = [Link](x => [Link] == "Matteo").ToList();
[Link](persons);[Link]();
After you’ve modified your entities or the DataContext definition in your project, you can use
the following methods:
if (![Link]())
[Link]();
[Link] = 2;
[Link]();
else
DatabaseSchemaUpdater updater =
[Link](); if
([Link] < 2)
[Link]<Person>("BirthDate");
[Link]
eSchemaVersio
n = 2;
[Link]
();
46
}
We’re assuming that the current database’s schema version is 2. In case the database
doesn’t exist, we simply create it and, using the DatabaseSchemaUpdater class, we update
the DatabaseSchemaVersion property. This way, the next time the data will be needed, the
update operation won’t be executed since we’re already working with the latest version.
Instead, if the database already exists, we check the version number. If it’s an older
version, we update the current schema. In the previous sample, we’ve added a new column to
the Person table, called BirthDate (which is the parameter requested by
the AddColumn<T>() method). Also in this case we need to remember to properly set
the DatabaseSchemaVersion property to avoid further executions of the update operation.
In both cases, we need to apply the described changes by calling the Execute() method.
Automatically create entities and a DataContext class starting from an already existing
SQL CE database.
The generated DataContext is able to copy a database from your Visual Studio project
47
to your application’s local storage. This way, you can start with a prepopulated database
and, at the same time, have write access.
The generated DataContext supports logging in the Visual Studio Output Window so
you can see the SQL queries generated by LINQ to SQL.
Advertisement
It offers better performance than SQL CE, especially with large amounts of data.
It is open source and cross-platform; you’ll find a SQLite implementation for Windows 8,
Android, iOS, web apps, etc.
SQLite support has been introduced only in Windows Phone 8 due to the new native code
support feature (since the SQLite engine is written in native code), and it’s available as a Visual
Studio extension that you can download from the Visual Studio website.
After you’ve installed it, you’ll find the SQLite for Windows Phone runtime available in
the Add reference window, in the Windows Phone Extension section. Be careful; this runtime
is just the SQLite engine, which is written in native code. If you need to use a SQLite database in
a C# application, you’ll need a third-party library that is able to execute the appropriate native
calls for you.
In actuality, there are two available SQLite libraries: sqlite-net and SQLite Wrapper for
Windows Phone. Unfortunately, neither of them is as powerful and flexible as the LINQ to SQL
library that is available for SQL CE.
48
Sqlite-net
Sqlite-net is a third-party library. The original version for Windows Store apps is
developed by Frank A. Krueger, while the Windows Phone 8 port is developed byPeter Huene.
The Windows Phone version is available on GitHub. Its configuration procedure is a bit tricky
and changes from time to time, so be sure to follow the directions provided by the developer on
the project’s home page.
Sqlite-net offers a LINQ approach to use the database that is similar to the code-first one offered
by LINQ to SQL with SQL CE.
For example, in sqlite-net, tables are mapped with your project’s entities. The difference is that,
this time, attributes are not required since every property will be automatically translated into a
column. Attributes are needed only if you need to customize the conversion process, as in the
following sample:
[Primary
Key,
AutoIncr
ement]
public
int Id {
get; set;
[MaxLength(50)]
49
public string Surname { get; set; }
All the basic operations with the database are accomplished using
the SQLiteAsyncConnection class, which exposes asynchronous methods to create tables, query
the data, delete items, etc. It requires as an input parameter the local storage path where the
database will be saved.
As with SQL CE and LINQ to SQL, we need to create the database before using it. This
is done by calling the CreateTableAsync<T>() method for every table we need to create,
where T is the table’s type. In the following sample, we create a table to store
the Person entity:
SQLiteAsyncConnection([Link]([Link].L await
[Link]<Person>();
In a similar way to LINQ to SQL, queries are performed using the Table<T> object. The only
difference is that all the LINQ methods are asynchronous.
"Matteo").ToListAsync();
In the previous sample, we retrieve all the Person objects whose name is Matteo.
automatically detect it and execute the operation on the proper table. In the following sample,
you can see how a new record is added to a table:
51
"
"
"
n
52
i
"
};
await [Link](person);
Sqlite-net is the SQLite library that offers the easiest approach, but it has many limitations. For
example, foreign keys are not supported, so it’s not possible to easily manage relationships.
SQLite Wrapper for Windows Phone has been developed directly by Microsoft team
members (notably Peter Torr and Andy Wigley) and offers a totally different approach than
sqlite-net. It doesn’t support LINQ, just plain SQL query statements.
The advantage is that you have total control and freedom, since every SQL feature is
supported: indexes, relationships, etc. The downside is that writing SQL queries for every
operation takes more time, and it’s not as easy and intuitive as using LINQ.
The key class is called Database , which takes care of initializing the database and offers
all the methods needed to perform the queries. As a parameter, you need to set the local storage
}
53
path to save the database. If the path doesn’t exist, it will be automatically created. Then, you
need to open the connection using the OpenAsync() method. Now you are ready to perform
operations.
There are two ways to execute a query based on the value it returns.
If the query doesn’t return a value—for example, a table creation—you can use
the ExecuteStatementAsync() method as shown in the following sample:
await [Link]();
“Name varchar(100), “ +
“Surname varchar(100))”;
await [Link](query);
The previous method simply executes the query against the opened database. In the sample, we
create a People table with two fields, Name and Surname .
The query, instead, can contain some dynamic parameters or return some values. In this case, we
need to introduce a new class called Statement as demonstrated in the following sample:
54
private async void OnAddDataClicked(object sender, RoutedEventArgs e)
await [Link]();
[Link](query);
[Link](“@name”,“Matteo”);
[Link](“@surname”, “Pagani”);
await [Link]();
}
The Statement class identifies a query, but it allows additional customization to be performed
with it. In the sample, we use it to assign a dynamic value to
the Name and Surname parameters. We set the placeholder using the @ prefix
( @name and @surname ), and then we assign them a value using
the BindTextParameterWithName() method, passing the parameter’s name and the value.
BindTextParameterWithName() isn’t the only available method, but it’s specifically for string
parameters. There are other methods based on the parameter’s type, such
as BindIntParameterWithName() for numbers.
To execute the query, we use the StepAsync() method. Its purpose isn’t just to execute the
query, but also to iterate the resulting rows.
In the following sample, we can see how this method can be used to manage the results of
a SELECT query: 55
private async void OnGetDataClicked(object sender, RoutedEventArgs e)
await [Link]();
[Link]([Link](0) + “ “ + [Link](1));
NETWORK COMMUNICATION
native development
Windows Phone 8
•In Windows Phone 7.x, the emulator shared the networking of the Host PC
•You could host services on your PC and access them from your code using [Link]
•In Windows Phone 8, the emulator is a Virtual machine running under Hyper-V
•You cannot access services on your PC using [Link]
•You must use the correct host name or raw IP address of your host PC in URIs
57
58
Operation TCP UDP
3 The client can request to receive data A UDP socket can receive data from a service
from the server. This is an by “listening” on the port associated with this
asynchronous call and, if successful, service for any incoming data, and processing
the resulting callback will contain the it as appropriate.
buffer of data that was sent.
4 The send and receive pattern in The client can continue to send and receive
operations 2 and data.
3 can be repeated for as long as the
socket remains connected.
7 At this point, there is no active socket At this point, there is no active socket channel,
channel, and data sent to the client will and data sent to the client will be lost.
be lost.
59
The following is a comparison of the characteristics of TCP and
UDP sockets on Windows Phone.
TCP UDP
Broadcast No No
Term Description
60
application that can consume a service over sockets.
61
Server A device on a network that provides a service, or multiple
services, for consumption by clients. As an example, a chat
server provides a chat service that can be used by chat
clients to establish chat sessions with other clients. Although
applications on a Windows Phone device can send and
receive data over a socket, they are not considered servers.
[Link] += client_DownloadStringCompleted;
{ [Link] = [Link];
62
}
63
private const int IANA_INTERFACE_TYPE_ETHERNET = 6;
private const int IANA_INTERFACE_TYPE_PPP = 23;
private const int IANA_INTERFACE_TYPE_WIFI = 71; ... string network = [Link];
// Get current Internet Connection Profile. ConnectionProfile internetConnectionProfile =
[Link]();
switch ([Link])
break;
break;
break;
default:
64
PUSH NOTIFICATION
1. Your app requests a push notification URI from the Push client service.
2. The Push client service negotiates with the Microsoft Push Notification Service (MPNS),
and MPNS returns a notification URI to the Push client service.
3. The Push client service returns the notification URI to your app.
4. Your app can then send the notification URI to your cloud service.
5. When your cloud service has info to send to your app, it uses the notification URI to send
a push notification to MPNS.
6. MPNS routes the push notification to your app.
Create a POST message for each Windows Phone device to which you want to send a
notification.
Form the message for the appropriate notification type. The following sections describe
the message formats for toast, Tile, and raw notification messages. You can post only one
notification type (toast, Tile, or raw) to the server at a time. If you want to send multiple
notification types to the same client device at the same time, you must create separate POST
messages for each notification type.
Post the messages to the push notification service.
Get the response from the push notification service and respond accordingly.
65
Custom HTTP headers can include a notification message ID, batching interval, the type
of push notification being sent, and the notification channel [Link] MessageID is the
notification message ID associated with the response. If this header is not added to the POST
request, the push notification service omits this header in the response.
The NotificationClass is the batching interval that indicates when the push notification will be
sent to the app from the push notification service. See the tables in the toast, Tile, and raw
notification sections for possible values for this header. If this header is not present, the message
will be delivered by the push notification service immediately.
The header specification is ”X-NotificationClass””:”1*NotificationClassValue
NotificationClassValue = DIGIT.
For example: X-NotificationClass:1
The Notification Type is the type of push notification being sent. Possible options are
Tile, toast, and raw. If this header is not present, the push notification will be treated as a raw
notification. For more info, see Push notifications for Windows Phone 8. The header
specification is “X-WindowsPhone-Target””:”1*NotificationTypeValue NotificationTypeValue
= STRING.
For example: X-WindowsPhone-Target:toast.
Special characters
The following characters should be encoded as shown in the table when used in a Tile or toast
payload.
< <
> >
& &
‘ '
“ "
66
The following sections describe payload info needed for sending a push notification to a
toast or Tile.
[Link] = "text/xml";
[Link]("X-WindowsPhone-Target", "toast");
[Link]("X-NotificationClass", "[batching interval]");
2 Immediate delivery.
1 Immediate delivery.
67
The following code shows an example of the Id attribute of the Tile element, which should
contain the exact navigation URI of the secondary Tile.
[Link] = "text/xml";
[Link]("X-NotificationClass", "[batching interval]");
The following table describes the values that the batching interval can have.
Value Delivery interval
3 Immediate delivery.
You can also pass a byte stream. The following code shows an example.
new byte[] {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
68
therefore have different behaviors and constraints. This topic describes the scheduling, duration,
and limitations of scheduled tasks.
ResourceIntensiv Resource-intensive agents run for a relatively long period of time when the
eTask phone meets a set of requirements relating to processor activity, power
source, and network connection. A typical scenario for this type of task is
synchronizing large amounts of data to the phone while it is not being
actively used by the user.
An application may have only one background agent. This agent can
be registered as a PeriodicTask, aResourceIntensiveTask, or both. The
schedule on which the agent runs depends on which type of task it is registered
as. The details of the schedules are described later in this topic. Only one
instance of the agent runs at a time.
When the agent has completed its task, it should call NotifyComplete()
or Abort() to let the operating system know that it has
[Link] should be used if the task was successful. If the
agent is unable to perform its task – such as a needed server being unavailable
- the agent should call Abort, which causes the IsScheduled property to be set
to false.
The following constraints apply to all Scheduled Tasks.
69
Unsupported APIs There is a set of APIs that cannot be used by any Scheduled Task. Using these
APIs either will cause an exception to be thrown at run time or will cause the
application to fail certification during submission to Store. For the list
of restricted APIs, see Unsupported APIs for background agents for
Windows Phone 8.
Memory usage Periodic agents and resource-intensive agents can use no more than 20 MB of
cap memory at any time on devices with 1 GB of memory or more.
Reschedule Use the ExpirationTime property of the ScheduledTask object to set the time
required every two after which the task no longer runs. This value must be set to a time within two
weeks weeks of the time when the action is scheduled with the Add(ScheduledAction)
method.
Agents Both periodic and resource-intensive agents are unscheduled if they exit two
unscheduled consecutive times due to exceeding the memory quota or any other unhandled
after two exception. The agents must be rescheduled by the foreground application.
consecuti
ve crashes
The following are the schedule, duration, and general constraints for Resource-intensive agents.
Constraint Description
Duration: Resource-intensive agents typically run for 10 minutes. There are other constraints that may cause
an agent to be terminated early.
10 minutes
External power Resource-intensive agents do not run unless the device is connected to an external power source.
required
Non-cellular Resource-intensive agents do not run unless the device has a network connection over Wi-Fi or
connection through a connection to a PC.
required
Minimum Resource-intensive agents do not run unless the device’s battery power is greater than 90%.
battery power
Device Resource-intensive agents do not run unless the device screen is locked.
scree
n lock required
No active phone Resource-intensive agents do not run while a phone call is active.
call
70
Introduction to Silverlight
71
72
73
74
75
ound Agents
e {
r
// Execute
e
periodic task
.
actions here.
toastMessag
O
e =
t
"Periodic
h
task
e
running.";
r
}
w
else
i
{
s
e // Execute resource-
here. toastMessage =
y "Resource-intensive
o task running.";
u }
[Link]
" nt =
B toastMessa
a ge;
c [Link]
k ();
r // If debugging is enabled,
u #if DEBUG_AGENT
n [Link]([Link],
[Link](60));
d
#endif
A
} g
// Call NotifyComplete
e to let the system know the agent is done working.
NotifyComplete();
n
e
79
The one caveat is that it can sometimes be difficult to debug in an emulator. If you have a
developer phone you will have a much easier time debugging it on the device.
Background Agents
80
81
Applications of Background Agents
82
83
Using maps and Locations The Maps app in Windows Phone can show you where you are,
84
where you want to go, and provide directions to get you there. It can also show you nearby shops
or restaurants you might be interested in and what other people are saying about them.
Displaying a Map
To display a map in your Windows Phone 8 app, use the Map control. For
more info, see How to add a Map control to a page in Windows Phone 8.
Important Note:
To use the control, you have to select the ID_CAP_MAP capability in the
app manifest file. For more info, see How to modify the app manifest file
for Windows Phone 8.
The following code example shows how you can use XAML to display a
Map control in your Windows Phone 8 app.
<!--ContentPanel - place additional content here-->
<maps:Map />
</Grid>
If you add the control by writing XAML, you also have to add the
following xmlns declaration to the phone:PhoneApplicationPage element.
If you drag and drop the Map control from the Toolbox, this declaration is
added automatically.
xmlns:maps="clr-
namespace:[Link];assembly=[Link]"
The following code example shows how you can use code to display a
Map control in your Windows Phone 8 app.
using [Link];
[Link](MyMap);
85
Displaying a Map by using a built-in launcher
This topic describes how to write code that displays a map inside your
app. If you simply want to display a map, you can also use the Maps task,
which launches the built-in Maps app. For more info, see How to use the
Maps task for Windows Phone 8.
The following table lists all the built-in launchers that display or manage
maps. For more info about launchers, see Launchers and Choosers for
Windows Phone 8.
Maps task Launches the built-in Maps app and optionally marks a
location.
Maps directions task Launches the built-in Maps app and displays directions.
86
Specifying the center of a map (XAML)
You can set the center of the Map control by using its Center property. To set the property using
XAML, assign a (latitude, longitude) pair to the Center property.
The following code example shows how you can set the center of Map by using XAML.
</Grid>
The following code example shows how can set the center of Map using code. (C#)
using [Link];
using [Link];
...
[Link](MyMap);
Use the ZoomLevel property to set the initial resolution at which you want to display the
map. ZoomLevel property takes values from 1 to 20, where 1 corresponds to a fully zoomed out
map, and higher zoom levels zoom in at a higher resolution. The following code examples show
how you can set the zoom level of the map by using the ZoomLevel property in XAML and
code.
The following code example shows how you can set the zoom level of the map by using the
ZoomLevel property in XAML.
87
<!--ContentPanel - place additional content here-->
</Grid>
The following code example shows how you can set the zoom level of the map by using the
ZoomLevel property in code. (C#)
using [Link];
using [Link];
...
[Link] = 10;
[Link](MyMap);
The Center property of the Map control requires a value of type GeoCoordinate from the
[Link] namespace. If you are using location services from the
[Link] namespace, you have to convert a
[Link] value to a
[Link] value for use with the Map control.
You can get an extension method to do this conversion, along with other useful
extensions to the Maps API, by downloading the Windows Phone Toolkit. If you want to write
your own code, here is an example of a method that you can use to convert a Geocoordinate to a
GeoCoordinate:
using System;
namespace CoordinateConverter
88
{
[Link],
[Link],
[Link] ?? [Link],
[Link],
[Link] ?? [Link],
[Link] ?? [Link],
[Link] ?? [Link]
);
89
The following illustration displays a map with landmarks and pedestrian features.
The following example shows how you can set the PedestrianFeaturesEnabled property and the
LandmarksEnabled property in XAML.
</Grid>
using [Link];
using [Link];
...
90
[Link] = 16;
[Link] = true;
[Link] = true;
[Link](MyMap);
Once you set the center and zoom level of a map, you You might may also want to set the
cartographic mode of the map. The cartographic mode defines the display and the translation of
coordinate systems from screen coordinates to world coordinates on the Map control. You can
use the CartographicMode property of the Map control to set the cartographic mode of the map.
This property takes accepts values from the MapCartographicMode enumeration. The following
types of cartographic modes are supported in the MapCartographicMode enumeration:
Hybrid: displays an aerial view of the map overlaid with roads and labels.
Terrain: displays physical relief images for displaying elevation and water features such as
mountains and rivers.
91
The following example displays a map in the default Road mode. The buttons in the app
bar can be used to view the map in Aerial, Hybrid, and Terrain modes.
XAML
<[Link]>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</[Link]>
</StackPanel>
</Grid>
</Grid>
<phone:[Link]>
</shell:ApplicationBar>
</phone:[Link]>
C#
[Link] = [Link];
[Link] = [Link];
[Link] = [Link];
93
[Link] = [Link];
You can display the map in a light color mode or a dark mode by using the ColorMode
property. The values that this property can take—Light or Dark—is accepts are specified
contained in the MapColorMode enumeration. The default is Light.
In the following illustration, the first map is in the Light color mode and the second map is in the
Dark color mode.
The following code example displays a map in the default Light mode. The buttons in the app
bar can be used to view the map in Light or Dark modes.
XAML
<[Link]>
<RowDefinition Height="Auto"/>
94
<RowDefinition Height="*"/>
</[Link]>
</StackPanel>
</Grid>
</Grid>
<phone:[Link]>
</shell:ApplicationBar>
</phone:[Link]>
C#
95
[Link] = [Link];
}
void Dark_Click(object sender, EventArgs args)
[Link] = [Link];
XAML
XAML --> Extensible Markup Language. XAML is very easy in use and it is tag based
language. There are different tags that do their work. It is tag based and when we open a tag
mostly it is necessary to close the same tag as same in HTML.
The Visual Studio 2015 Start page appears. (From now on, we'll refer to Visual Studio 2015
simply as Visual Studio .)
The New Project dialog appears. The left pane of the dialog lets you select the type of templates
to display.
3. In the left pane, expand Installed > Templates > Visual C# > Windows, then pick
the Universal template group. The dialog's center pane displays a list of project templates for
Universal Windows Platform (UWP) apps.
96
4. In the center pane, select the Blank App (Universal Windows) template.
The Blank App template creates a minimal UWP app that compiles and runs, but contains no
user-interface controls or data. You add controls to the app over the course of this tutorial.
Visual Studio creates your project and displays it in the Solution Explorer.
97
Although the Blank App is a minimal template, it still contains a lot of files:
A manifest file ([Link]) that describes your app (its name, description,
tile, start page, and so on) and lists the files that your app contains.
A set of logo images (Assets/[Link],
Assets/[Link], and Assets/[Link])to
display in the start menu.
An image (Assets/[Link]) to represent your app in the Windows Store.
A splash screen (Assets/[Link]) to display when your app starts.
XAML and code files for the app ([Link] and [Link]).
A start page ([Link]) and an accompanying code file ([Link]) that
run when your app starts.
These files are essential to all UWP apps using C#. Every project that you create in Visual Studio
contains them.
Step 2: Modify your start page
To view and edit a file in your project, double-click the file in the Solution Explorer. By
default, you can expand a XAML file just like a folder to see its associated code file. XAML
files open in a split view that shows both the design surface and the XAML editor.
In this tutorial, you work with just a few of the files listed previously: [Link],
[Link], and [Link].
[Link] is where you declare resources that are used across the app. [Link] is the
code-behind file for [Link]. Code-behind is the code that is joined with the XAML page's
partial class. Together, the XAML and code-behind make a complete class. [Link] is the
entry point for your app. Like all code-behind pages, it contains a constructor that calls
the InitializeComponent method. You don't write the InitializeComponent method. It's generated
by Visual Studio, and its main purpose is to initialize the elements declared in the XAML file.
[Link] also contains methods to handle activation and suspension of the app.
[Link]
In [Link] you define the UI for your app. You can add elements directly using
XAML markup, or you can use the design tools provided by Visual Studio. [Link] is
the code-behind page for [Link]. It's where you add your app logic and event handlers.
Together these two files define a new class called MainPage, which inherits from Page, in
the HelloWorld namespace.
[Link]
<Page
x:Class="[Link]"
98
xmlns="[Link]
xmlns:x="[Link]
xmlns:local="using:HelloWorld"
xmlns:d="[Link]
xmlns:mc="[Link]
mc:Ignorable="d">
using [Link];
using [Link];
namespace HelloWorld
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
[Link]();
}
}
}
Now, let's add some content to the app. To modify the start page
In the root Grid, add this XAML. It contains a StackPanel with a title TextBlock,
a TextBlock that asks the user's name, a TextBox element to accept the user's name, a Button,
and another TextBlock to show a greeting. Some of these controls have names so that you can
refer to them later in your code.
At this point, you've created a very simple app. This is a good time to build, deploy, and launch
your app and see what it looks like. You can debug your app on the local machine, in a simulator
or emulator, or on a remote device. Here's the target device menu in Visual Studio.
By default, the app runs on the local machine. The target device menu provides several options
for debugging your app on devices from the desktop device family.
Simulator
Local Machine
Remote Machine
Press the Windows key to open the Start menu, then show all apps. Notice that deploying the
app locally adds its tile to the Start menu. To run the app again (not in debugging mode), tap or
click its tile in the Start menu.
It doesn't do much—yet—but congratulations, you've built your first UWP app!
To stop debugging
Click the Stop Debugging button ( ) in the toolbar.
–or–
From the Debug menu, click Stop debugging.
–or–
Close the app window.
Your app runs on any Windows 10 device, so let’s see how it looks on a Windows Phone.
In addition to the options to debug on a desktop device, Visual Studio provides options for
deploying and debugging your app on a physical mobile device connected to the computer, or on
a mobile device emulator. You can choose among emulators for devices with different memory
and display configurations.
Device
Emulator <SDK version> WVGA 4 inch 512MB
Emulator <SDK version> WVGA 4 inch 1GB
etc... (Various emulators in other configurations)
It's a good idea to test your app on a device with a small screen and limited memory, so use
the Emulator 10.0.10240.0 WVGA 4 inch 512MB option.
To start debugging on a mobile device emulator
101
–or–
From the Debug menu, click Start Debugging.
–or–
Press F5.
Visual Studio starts the selected emulator and then deploys and starts your app. On the mobile
device emulator, the app looks like this.
The first thing you'll notice is the button is pushed off the smaller screen of a mobile device.
Later in this tutorial, you'll learn how to adapt the UI to different screen sizes so your app always
looks good.
You might also notice that you can type in the TextBox, but right now, clicking or tapping
the Button doesn't do anything. In the next steps, you create an event handler for the
button's Click event to display a personalized greeting. You add the event handler code to your
[Link] file.
Step 4: Create an event handler
XAML elements can send messages when certain events occur. These event messages give you
the opportunity to take some action in response to the event. You put your code to respond to the
event in an event handler method. One of the most common events in many apps is a user
clicking a Button.
Let's create an event handler for your button's Click event. The event handler will get the user's
name from the nameInputTextBox control and use it to output a greeting to
the greetingOutput TextBlock.
Using events that work for touch, mouse, and pen input
What events should you handle? Because they can run on a variety of devices, design
your Windows Store apps with touch input in mind. Your app must also be able to handle input
from a mouse or a stylus. Fortunately, events such asClick and DoubleTapped are device-
independent. If you're familiar with Microsoft .NET programming, you might have seen separate
events for mouse, touch, and stylus input, like MouseMove, TouchMove, and StylusMove. In
Windows Store apps, these separate events are replaced with a single PointerMoved event that
works equally well for touch, mouse, and stylus input.
To add an event handler
102
1. In XAML or design view, select the "Say Hello" Button that you added to
[Link].
2. In the Properties Window, click the Events button ( ).
3. Find the Click event at the top of the event list. In the text box for the event, type the
name of the function that handles the Click event. For this example, type "Button_Click".
4. Press Enter. The event handler method is created and opened in the code editor so you
can add code to be executed when the event occurs.
In the XAML editor, the XAML for the Button is updated to declare the Click event handler like
this.
<Button x:Name="inputButton" Content="Say "Hello"" Click="Button_Click"/>
5. Add code to the event handler that you created in the code-behind page. In the event
handler, retrieve the user's name from the nameInput TextBox control and use it to create a
greeting. Use the greetingOutput TextBlock to display the result.
6. Debug the app on the local machine. When you enter your name in the text box and click
the button, the app displays a personalized greeting.
103
Step 5: Adapt the UI to different window sizes
Now we'll make the UI adapt to different screen sizes so it looks good on mobile devices. To do
this, you add aVisualStateManager and set properties that are applied for different visual states.
To adjust the UI layout
1. In the XAML editor, add this block of XAML after the opening tag of the
root Grid element.
<[Link]>
<VisualStateGroup>
<VisualState x:Name="wideState">
<[Link]>
<AdaptiveTrigger MinWindowWidth="641" />
</[Link]>
</VisualState>
<VisualState x:Name="narrowState">
<[Link]>
<AdaptiveTrigger MinWindowWidth="0" />
</[Link]>
<[Link]>
<Setter Target="[Link]" Value="Vertical"/>
<Setter Target="[Link]" Value="0,4,0,0"/>
</[Link]>
</VisualState>
</VisualStateGroup>
</[Link]>
2. Debug the app on the local machine. Notice that the UI looks the same as before unless
the window gets narrower than 641 pixels.
3. Debug the app on the mobile device emulator. Notice that the UI uses the properties you
defined in the narrowStateand appears correctly on the small screen.
If you've used a VisualStateManager in previous versions of XAML, you might notice that the
XAML here uses a simplified syntax.
The VisualState named wideState has an AdaptiveTrigger with
its MinWindowWidth property set to 641. This means that the state is to be applied only when
104
the window width is not less than the minimum of 641 pixels. You don't define anySetter objects
for this state, so it uses the layout properties you defined in the XAML for the page content.
The second VisualState, narrowState, has an AdaptiveTrigger with
its MinWindowWidth property set to 0. This state is applied when the window width is greater
than 0, but less than 641 pixels. (At 641 pixels, the wideState is applied.) In this state, you do
define some Setter objects to change the layout properties of controls in the UI:
You change the Orientation of the inputPanel element from Horizontal to Vertical.
You add a top margin of 4 to the inputButton element.
Summary
Congratulations, you've created your first app for Windows 10 and the UWP!
Adding controls and handling events (XAML)
You create the UI for your app by using controls such as buttons, text boxes, and combo boxes.
Here we show you how to add controls to your app. You typically use this pattern when working
with controls:
Use a design tool like Blend for Visual Studio or the Microsoft Visual Studio XAML
designer.
Add the control to the XAML markup in the Visual Studio XAML editor.
Add the control in code. Controls that you add in code are visible when the app runs, but
are not visible in the Visual Studio XAML designer.
Documentation for each control includes a "How to" topic that describes how to add the control
in XAML, code, or using a design tool. For example, to add a Button control, see How to add a
button.
Here, we use Visual Studio as our design tool, but you can do the same tasks and more in Blend
for Visual Studio.
In Visual Studio, when you add and manipulate controls in your app, you can use many of the
program's features, including the Toolbox, XAML designer, XAML editor, and
the Properties window.
The Visual Studio Toolbox displays many of the controls that you can use in your app. To add a
control to your app, double-click it in the Toolbox. For example, when you double-click
the TextBox control, this XAML is added to the XAMLview.
To work with a control in code, you set its x:Name attribute and reference it by name in your
code. You can set the name in the Visual Studio Properties window or in XAML. Here's how to
change the name of the currently selected control by using the Name text box at the top of
the Properties window.
To name a control
Here's how you can change the name of a control in the XAML editor by changing
the x:Name attribute.
You use properties to specify the appearance, content, and other attributes of controls. When you
add a control using a design tool, some properties that control size, position, and content might
be set for you by Visual Studio. You can change some properties, such
as Width, Height or Margin, by selecting and manipulating the control in the Design view. This
illustration shows some of the resizing tools available in Design view.
You might want to let the control be sized and positioned automatically. In this case, you can
reset the size and position properties that Visual Studio set for you.
To reset a property
1. In the Properties panel, click the property marker next to the property value. The
property menu opens.
106
2. In the property menu, click Reset.
You can set control properties in the Properties window, in XAML, or in code. For example, to
change the foreground color for a Button, you set the control's Foreground property. This
illustration shows how to set the Foregroundproperty by using the color picker in
the Properties window.
107
Here's how to set the Foreground property in the XAML editor. Notice the Visual Studio
IntelliSense window that opens to help you with the syntax.
108
Here's the resulting XAML after you set the Foreground property.
XAML
Each control has events that enable you to respond to actions from your user or other changes in
your app. For example, a Button control has a Click event that is raised when a user clicks
the Button. You create a method, called an event handler, to handle the event. You can associate
a control's event with an event handler method in the Propertieswindow, in XAML, or in code.
For more info about events, see Events and routed events overview.
To create an event handler, select the control and then click the Events tab at the top of
the Properties window. TheProperties window lists all of the events available for that control.
Here are some of the events for a Button.
110
To create an event handler with the default name, double-click the text box next to the
event name in the Propertieswindow. To create an event handler with a custom name, type the
name of your choice into the text box and press enter. The event handler is created and the code-
behind file is opened in the code editor. The event handler method has 2 parameters. The first
is sender, which is a reference to the object where the handler is attached. The sender parameter
is anObject type. You typically cast sender to a more precise type if you expect to check or
change state on the sender object itself. Based on your own app design, you expect a type that is
safe to cast sender to, based on where the handler is attached. The second value is event data,
which generally appears in signatures as the e parameter.
Here's code that handles the Click event of a Button named Button1. When you click the button,
the Foreground property of the Button you clicked is set to blue. C#, C++, VB
111
event handler from the list. Here's the IntelliSense window that appears to
help you create a new event handler.
You can also associate an event with its event handler in the code-behind.
Here's how to associate an event handler in code. C#, C++, VB
New controls
If you use other XAML platforms, you might be interested in these controls
that are new for Windows 8.
AppBar
CaptureElement
FlipView
GridView
SemanticZoom
ProgressRing
ToggleSwitch
VariableSizedWrapGrid
You learned how to create TextBlock controls to display text in your app.
113
Adding text input and editing controls (XAML)
The XAML framework includes several controls for entering and editing text, and a set
of properties for formatting the text. The text-entry controls areTextBox,PasswordBox,
and RichEditBox. This quickstart shows you how you can use these text controls to display,
enter, and edit text.
Choosing a text control
Recommended Control
Scenario
You can use a TextBox control to enter and edit unformatted text. You can use the Text property
to get and set the text in a TextBox. Here's the XAML for a simple TextBox with
it's Text property set.
You can make a TextBox read-only by setting the IsReadOnly property to true. To make the
text in a multi-line TextBoxwrap, set the TextWrapping property to Wrap and
the AcceptsReturn property to true.
You can get or set the selected text in a TextBox using the SelectedText property. Use
the SelectionChanged event to do something when the user selects or de-selects text.
114
Here, we have an example of these properties and methods in use. When you select text in the
first TextBox, the selected text is displayed in the second TextBox, which is read-only. The
values of the SelectionLength and SelectionStartproperties are shown in two TextBlocks. This
is done using the SelectionChanged event.
PasswordBox
You can enter a single line of non-wrapping content in a PasswordBox control. The user
cannot view the entered text; only password characters that represents the text are displayed. You
can specify this password character by using thePasswordChar property, and you can specify
the maximum number of characters that the user can enter by setting theMaxLength property.
115
You get the text that the user entered from the Password property, typically in the handler for
the PasswordChangedevent.
Here's the XAML for a password box control that demonstrates the default look of
the PasswordBox. When the user enters a password, it is checked to see if it is the literal value,
"Password". If it is, we display a message to the user.
XAML
// C#
private void pwBox_PasswordChanged(object sender, RoutedEventArgs e)
{
if ([Link] == "Password")
{
[Link] = "'Password' is not allowed as a password.";
}
}
Here's the result when this code runs and the user enters "Password".
In Windows Store apps, the PasswordBox has a built-in button that the user can touch or click to
display the password text. Here's the result of the user's action. When the user releases it, the
password is automatically hidden again.
In Windows Phone Store apps, the PasswordBox has a built-in checkbox below it that the user
can check to display the password text.
116
RichEditBox
You can use a RichEditBox control to enter and edit rich text documents that contain
formatted text, hyperlinks, and images. You can make a RichEditBox read-only by setting
its IsReadOnly property to true.
By default, the RichEditBox supports spell checking. To disable the spell checker, set
the IsSpellCheckEnabled property to false. For more info, see Guidelines and checklist for spell
checking.
You use the Document property of the RichEditBox to get its content. The content of
a RichEditBox is [Link] object, unlike
the RichTextBlock control, which [Link] objects as its
content. The ITextDocument interface provides a way to load and save the document to a
stream, retrieve text ranges, get the active selection, undo and redo changes, set default
formatting attributes, and so on.
This example shows how to load and save a Rich Text Format (rtf) file in a RichEditBox.
<Grid Margin="120">
<[Link]>
<RowDefinition Height="50"/>
<RowDefinition/>
</[Link]>
<StackPanel Orientation="Horizontal">
<Button Content="Open file" Click="OpenButton_Click"/>
<Button Content="Save file" Click="SaveButton_Click"/>
</StackPanel>
// Default file name if the user does not type one in or select a file to replace
[Link] = "New Document";
[Link]([Link],
randAccStream);
// Let Windows know that we're finished changing the file so the
118
// other app can update the remote version of the file.
FileUpdateStatus status = await
[Link](file); if (status !=
[Link])
saved.");
}
}
}
}
Using the touch keyboard
The touch keyboard can be used for text entry when your app runs on a
device with a touch screen. The touch keyboard is invoked when the user taps
on an editable input field, such as a TextBox or PasswordBox, and is dismissed
when the input field loses focus. The touch keyboard uses accessibility info to
determine when it is invoked and dismissed. The text controls provided in the
XAML framework have the automation properties built in. If you create your
own custom text controls, you must implement TextPattern to use the touch
keyboard.
120
Check that you have all the images that are required for a Universal Windows
app on the Visual Assets tab.
From the Packaging tab, you can enter publishing data. This is where you can
choose which certificate to use to sign your app. All Universal Windows Apps
must be signed with a certificate. In order to sideload an app package, you need
to trust the package. The certificate must be installed on that device to trust the
package.
4. Save your file after you have made the necessary
edits for your app. Create an app package
To distribute an app through the Store you must create an appxupload package.
You can do that by using the Create App Packages wizard. Follow these steps
to create a package suitable for store submission with Visual Studio 2015:
Windows project.
121
If you choose No here, Visual Studio will not generate the required .appxupload
package you need for store submission. If you only want to sideload your app to
run it on internal devices, then you can select this option.
4. Sign in with your developer account to the Windows Dev Center. (If you
don’t have a developer account yet, the wizard will help you create one.)
5. Select the app name for your package, or reserve a new one if you have
not already reserved one with the Windows Dev Center portal.
6. Make sure you select all three architecture configurations (x86, x64,
and ARM) in the Select and Configure Packages dialog. That way your app
can be deployed to the widest range of devices. In the Generate app
bundlelistbox, select Always. This makes the store submission process much
simpler because you will only have one file to upload (.appxupload). The single
bundle will contain all the necessary packages to deploy to devices with each
processor architecture.
122
7. It is a good idea to include full PDB symbol files for the best crash analytics experience
from the Windows Dev Center.
8. Now you can configure the details to create your package. When you’re ready to publish
your app, you’ll upload the packages from the output location.
9. Click Create to generate your appxupload package.
10. Now you will see this dialog:
123
Validate your app before you submit it to the Store for certification on a local or remote machine.
(You can only validate release builds for your app package and not debug builds.)
11. To validate locally, leave the Local machine option selected and click Launch
Windows App Certification Kit.
The Windows App Certification Kit performs tests and shows you the results.
If you have a remote Windows 10 device, that you want to use for testing, you will need to
install the Windows App Certification Kit manually on that device. The next section will walk
you through these steps. Once you’ve done that, then you can select Remote machine and
click Launch Windows App Certification Kit to connect to the remote device and run the
validation tests.
12. After WACK has finished and your app has passed, you are ready to upload to the store.
Make sure you upload the correct file. It can be found in the root folder of your solution
\[AppName]\AppPackages and it will end with .appxupload file extension. The name will be of
the form [AppName]_[AppVersion]_x86_x64_arm_bundle.appxupload.
125
When the app package has been installed, you will see this message in
your PowerShell window: Your app was successfully installed.
4. Click the Start button and then type the name of your app to
launch it.
126