SlideShare une entreprise Scribd logo
1  sur  58
Télécharger pour lire hors ligne
Model Driven
App Development
@peterfriese | @itemismobile
http://peterfriese.de | http://mobile.itemis.de
for iPhone
and Android
AWESOME
OUR GOAL
BEING
Great, so...
How to be Awesome?
How to be Awesome?
Time
to
Market
Happy
Users
Precision.Great
Ideas
How to be Awesome?
Time
to
Market
Happy
Users
Precision.Great
Ideas
Great
Ideas
How to be Awesome?
Time
to
Market
Happy
Users
Great
Ideas
Precision.
How to be Awesome?
Happy
Users
Precision.Great
Ideas
Time
to
Market
How to be Awesome?
Time
to
Market
Precision.Great
Ideas
Happy
Users
There Are 4 Things That Keep
Us From Being Awesome
Accidental
Complexity
Wrong Level
of
Abstraction
Ugly
Design
Boring
Code
There Are 4 Things That Keep
Us From Being Awesome
Accidental
Complexity
Wrong Level
of
Abstraction
Ugly
Design
Boring
Code
There Are 4 Things That Keep
Us From Being Awesome
Wrong Level
of
Abstraction
Ugly
Design
Boring
Code
Accidental
Complexity
There Are 4 Things That Keep
Us From Being Awesome
Ugly
Design
Boring
Code
Accidental
Complexity
Wrong Level
of
Abstraction
There Are 4 Things That Keep
Us From Being Awesome
Boring
Code
Accidental
Complexity
Wrong Level
of
Abstraction
Ugly
Design
Oh, did I mention
Oh, did I mention
Bugs
Redundancy
Multi-
Platform
Challenges vs. Threats
Time
to
Market
Happy
Users
Precision.Great
Ideas
Accidental
Complexity
Wrong Level
of
Abstraction
Ugly
Design
Boring
Code
Challenges vs. Threats
Time
to
Market
Happy
Users
Precision.Great
Ideas
Accidental
Complexity
Wrong Level
of
Abstraction
Ugly
Design
Boring
Code
not in this talk
not in this talk
Accidental
Complexity
Wrong Level
of
Abstraction
Boring
Code
Time
to
Market
Happy
Users
Precision.
Bugs
Redundancy
Multi-
Platform
Accidental
Complexity
Wrong Level
of
Abstraction
Boring
Code
Time
to
Market
Happy
Users
Precision.
Bugs
Redundancy
Multi-
Platform
Is there anything we can
do about all this?
YES, there is.
Why?
... is code so boring (at times)?
... is there so much accidental complexity?
... is there so much redundancy?
... is our code so buggy?
Wrong Level of Abstraction!
... is code so boring (at times)?
... is there so much accidental complexity?
... is there so much redundancy?
... is our code so buggy?
Software artifact
Anatomy of Modern Software
Libraries
Frameworksmanually written code
Anatomy of Modern Software
schematic code (manually written)
Libraries
Frameworks
manually written
code
Anatomy of Modern Software
RESTRICTIONS
GAIN VELOCITY
THROUGH
Text
Lists Details Custom
DOMAIN
ANALYZING
THE
http://www.flickr.com/photos/jakematesdesign/4689135843/
Anatomy
of Data-Driven
Apps
Cells
View
Navigation
Cells
View
Navigation
Name
Image
Speaker
Title
Location
Session
Entity
Data Provider
LANGUAGE
DOMAIN
SPECIFIC
BUILDING A
http://en.wikipedia.org/wiki/File:Rosetta_Stone.JPG
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
-(UIViewController*)createController {
! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease];
! UITabBarController *result = [[UITabBarController alloc] init];
! NSMutableArray *controllers = [NSMutableArray array];
!
! UIViewController<IPUIView> *controller;
! UINavigationController *navController;
! IPContentProvider *contentProvider;
! // controller for @"Tuesday"
! contentProvider = [providers providerForSessionsByDay: @"0"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Tuesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Wednesday"
! contentProvider = [providers providerForSessionsByDay: @"1"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Wednesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Thursday"
! contentProvider = [providers providerForSessionsByDay: @"2"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Thursday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Speakers"
! contentProvider = [providers providerForAllSpeakers];
!
! controller = [[SpeakersListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Speakers";
! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
! result.viewControllers = controllers;
! return result;
}
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
-(UIViewController*)createController {
! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease];
! UITabBarController *result = [[UITabBarController alloc] init];
! NSMutableArray *controllers = [NSMutableArray array];
!
! UIViewController<IPUIView> *controller;
! UINavigationController *navController;
! IPContentProvider *contentProvider;
! // controller for @"Tuesday"
! contentProvider = [providers providerForSessionsByDay: @"0"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Tuesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Wednesday"
! contentProvider = [providers providerForSessionsByDay: @"1"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Wednesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Thursday"
! contentProvider = [providers providerForSessionsByDay: @"2"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Thursday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Speakers"
! contentProvider = [providers providerForAllSpeakers];
!
! controller = [[SpeakersListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Speakers";
! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
! result.viewControllers = controllers;
! return result;
}
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
-(UIViewController*)createController {
! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease];
! UITabBarController *result = [[UITabBarController alloc] init];
! NSMutableArray *controllers = [NSMutableArray array];
!
! UIViewController<IPUIView> *controller;
! UINavigationController *navController;
! IPContentProvider *contentProvider;
! // controller for @"Tuesday"
! contentProvider = [providers providerForSessionsByDay: @"0"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Tuesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Wednesday"
! contentProvider = [providers providerForSessionsByDay: @"1"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Wednesday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Thursday"
! contentProvider = [providers providerForSessionsByDay: @"2"];
!
! controller = [[SessionListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Thursday";
! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
!
! // controller for @"Speakers"
! contentProvider = [providers providerForAllSpeakers];
!
! controller = [[SpeakersListViewController alloc] init];
! [controller setContentProvider: contentProvider];
! controller.tabBarItem.title = @"Speakers";
! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"];
! navController = [[UINavigationController alloc] initWithRootViewController:controller];
! [controllers addObject: navController];
! [controller release];
! [navController release];
! result.viewControllers = controllers;
! return result;
}
135
http://www.xtext.org
ENGINE
TEMPLATE
GENERATE
CODE
WITH A
«DEFINE moduleFile FOR Application»
«FILE filenameApplicationDelegateModule()»
#import "«filenameApplicationDelegateHeader()»"
#import "IPUIView.h"
#import "«filenameCentralProvidersHeader()»"
«EXPAND importStatements-»
@implementation «applicationDelegateClassname()»
@synthesize window, rootController;
-(UIViewController*)createController {
	 «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease];
	 UITabBarController *result = [[UITabBarController alloc] init];
	 NSMutableArray *controllers = [NSMutableArray array];
	
	 UIViewController<IPUIView> *controller;
	 UINavigationController *navController;
	 IPContentProvider *contentProvider;
«EXPAND barControllerInstance FOREACH buttons»
	 result.viewControllers = controllers;
	 return result;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	 self.rootController = [self createController];
	 [window addSubview: [self.rootController view]];
[window makeKeyAndVisible];
}
- (void)dealloc {
	 self.rootController = nil;
[window release];
[super dealloc];
}
@end
«ENDFILE»
«ENDDEFINE»
«DEFINE moduleFile FOR Application»
«FILE filenameApplicationDelegateModule()»
#import "«filenameApplicationDelegateHeader()»"
#import "IPUIView.h"
#import "«filenameCentralProvidersHeader()»"
«EXPAND importStatements-»
@implementation «applicationDelegateClassname()»
@synthesize window, rootController;
-(UIViewController*)createController {
	 «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease];
	 UITabBarController *result = [[UITabBarController alloc] init];
	 NSMutableArray *controllers = [NSMutableArray array];
	
	 UIViewController<IPUIView> *controller;
	 UINavigationController *navController;
	 IPContentProvider *contentProvider;
«EXPAND barControllerInstance FOREACH buttons»
	 result.viewControllers = controllers;
	 return result;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	 self.rootController = [self createController];
	 [window addSubview: [self.rootController view]];
[window makeKeyAndVisible];
}
- (void)dealloc {
	 self.rootController = nil;
[window release];
[super dealloc];
}
@end
«ENDFILE»
«ENDDEFINE»
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
«DEFINE moduleFile FOR Application»
«FILE filenameApplicationDelegateModule()»
#import "«filenameApplicationDelegateHeader()»"
#import "IPUIView.h"
#import "«filenameCentralProvidersHeader()»"
«EXPAND importStatements-»
@implementation «applicationDelegateClassname()»
@synthesize window, rootController;
-(UIViewController*)createController {
	 «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease];
	 UITabBarController *result = [[UITabBarController alloc] init];
	 NSMutableArray *controllers = [NSMutableArray array];
	
	 UIViewController<IPUIView> *controller;
	 UINavigationController *navController;
	 IPContentProvider *contentProvider;
«EXPAND barControllerInstance FOREACH buttons»
	 result.viewControllers = controllers;
	 return result;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
	 self.rootController = [self createController];
	 [window addSubview: [self.rootController view]];
[window makeKeyAndVisible];
}
- (void)dealloc {
	 self.rootController = nil;
[window release];
[super dealloc];
}
@end
«ENDFILE»
«ENDDEFINE»
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
«DEFINE barControllerInstance FOR TabbarButton»
	 «IF view.provider != null»
	 // controller for «this.title.expression('', '')»
	 contentProvider = «view.provider.contentProvider('providers', '', '')»;
	 «ENDIF»
	 controller = [[«view.view.className()» alloc] init];
	 [controller setContentProvider: contentProvider];
	 controller.tabBarItem.title = «title.expression('', '')»;
	 controller.tabBarItem.image =
	 	 [UIImage imageNamed:«this.icon.expression('','')»];
	 navController =
	 	 [[UINavigationController alloc]
	 	 	 initWithRootViewController:controller];
	 [controllers addObject: navController];
	 [controller release];
	 [navController release];
«ENDDEFINE»
tabbarApplication itemisApp {
	 button {
	 	 title= "Tuesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("0") )
	 }
	 button {
	 	 title= "Wednesday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("1") )
	 }
	
	 button {
	 	 title= "Thursday"
	 	 icon= "calendar.png"
	 	 view= SessionList( SessionsByDay("2") )
	 }
	
	 button {
	 	 title= "Speakers"
	 	 icon= "person.png"
	 	 view= SpeakersList( AllSpeakers() )
	 }
}
INTEGRATION
TOOL
BUILDER
PROJECT
XCODE
INVOKE
DEMO
FUTURE
THE
SourceUI (Apple TV)
iPhone App
iPad App
Apple TV App
UI (iPad)
UI (iPhone)
@mschluepmann:
iPhone App
iPad App
TV App
@APPlauseDSL:
APPlause
DSL Program
APPlause
DSL
DEMO
code
Open source - EPL 1.0
code.google.com/p/applause/
‣ Showcase about conferences
‣ Tighter integration with Xcode
‣ Improved Android Generator
‣ Support for BlackBerry
‣ Support for Windows Phone 7
‣ Support for TV sets?
APPlause - Roadmap
@peterfriese | http://peterfriese.de
http://mobile.itemis.de

Contenu connexe

Tendances

Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverageroastedrecluse128
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money Newseminentoomph4388
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC Newsenchantingsched84
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverageexcitedfoyer2246
 
U.S. News | National News
U.S. News | National NewsU.S. News | National News
U.S. News | National Newscoldpoet326
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC Newsgapingtrousers365
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverageplantresidence159
 
Health News & Articles | Healthy Living
Health News & Articles | Healthy LivingHealth News & Articles | Healthy Living
Health News & Articles | Healthy Livingseemlygown2854
 
New BYOB Law for Sayreville (The Suburban)
New BYOB Law for Sayreville (The Suburban)New BYOB Law for Sayreville (The Suburban)
New BYOB Law for Sayreville (The Suburban)Jacqueline Durett
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC Newstalloration5719
 
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)South Amboy of 1920s Is Theme of Fundraiser (The Suburban)
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)Jacqueline Durett
 
International News | World News
International News | World NewsInternational News | World News
International News | World Newsblogginatl1963
 
J Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham SiddiquiJ Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham SiddiquiMuhammad Ehtisham Siddiqui
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC Newspainstakingsled66
 
What Would You Do? With John Quinones
What Would You Do? With John QuinonesWhat Would You Do? With John Quinones
What Would You Do? With John Quinonesalertchair8725
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coveragegreedycabin1256
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC Newsnumberlesspasto93
 

Tendances (18)

Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverage
 
Business News, Personal Finance and Money News
Business News, Personal Finance and Money NewsBusiness News, Personal Finance and Money News
Business News, Personal Finance and Money News
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC News
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverage
 
U.S. News | National News
U.S. News | National NewsU.S. News | National News
U.S. News | National News
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC News
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverage
 
Health News & Articles | Healthy Living
Health News & Articles | Healthy LivingHealth News & Articles | Healthy Living
Health News & Articles | Healthy Living
 
New BYOB Law for Sayreville (The Suburban)
New BYOB Law for Sayreville (The Suburban)New BYOB Law for Sayreville (The Suburban)
New BYOB Law for Sayreville (The Suburban)
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC News
 
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)South Amboy of 1920s Is Theme of Fundraiser (The Suburban)
South Amboy of 1920s Is Theme of Fundraiser (The Suburban)
 
International News | World News
International News | World NewsInternational News | World News
International News | World News
 
J Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham SiddiquiJ Query (Complete Course) by Muhammad Ehtisham Siddiqui
J Query (Complete Course) by Muhammad Ehtisham Siddiqui
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC News
 
What Would You Do? With John Quinones
What Would You Do? With John QuinonesWhat Would You Do? With John Quinones
What Would You Do? With John Quinones
 
U.S. News | National News
U.S. News | National NewsU.S. News | National News
U.S. News | National News
 
Politics News and U.S. Elections Coverage
Politics News and U.S. Elections CoveragePolitics News and U.S. Elections Coverage
Politics News and U.S. Elections Coverage
 
Technology and Science News - ABC News
Technology and Science News - ABC NewsTechnology and Science News - ABC News
Technology and Science News - ABC News
 

Similaire à Model Driven App Development for iPhone and Android

Beginning iphone 4_devlopement_chpter7_tab_b
Beginning iphone 4_devlopement_chpter7_tab_bBeginning iphone 4_devlopement_chpter7_tab_b
Beginning iphone 4_devlopement_chpter7_tab_bJihoon Kong
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder BehindJohn Wilker
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applicationslmrei
 
Static Reference Analysis for GUI Objects in Android Software
Static Reference Analysis for GUI Objects in Android SoftwareStatic Reference Analysis for GUI Objects in Android Software
Static Reference Analysis for GUI Objects in Android SoftwareDacong (Tony) Yan
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentanistar sung
 
Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with IonicMorris Singer
 
iOS Beginners Lesson 4
iOS Beginners Lesson 4iOS Beginners Lesson 4
iOS Beginners Lesson 4Calvin Cheng
 
Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4성일 한
 
Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月Eihiro Saishu
 
Ionic bbl le 19 février 2015
Ionic bbl le 19 février 2015Ionic bbl le 19 février 2015
Ionic bbl le 19 février 2015Loïc Knuchel
 
Lightning Components Workshop
Lightning Components WorkshopLightning Components Workshop
Lightning Components WorkshopGordon Bockus
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаГлеб Тарасов
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersJoris Verbogt
 
Implement angular calendar component how to drag &amp; create events
Implement angular calendar component how to drag &amp; create eventsImplement angular calendar component how to drag &amp; create events
Implement angular calendar component how to drag &amp; create eventsKaty Slemon
 
Apple Templates Considered Harmful
Apple Templates Considered HarmfulApple Templates Considered Harmful
Apple Templates Considered HarmfulBrian Gesiak
 

Similaire à Model Driven App Development for iPhone and Android (20)

Beginning iphone 4_devlopement_chpter7_tab_b
Beginning iphone 4_devlopement_chpter7_tab_bBeginning iphone 4_devlopement_chpter7_tab_b
Beginning iphone 4_devlopement_chpter7_tab_b
 
Leaving Interface Builder Behind
Leaving Interface Builder BehindLeaving Interface Builder Behind
Leaving Interface Builder Behind
 
занятие6
занятие6занятие6
занятие6
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
 
Static Reference Analysis for GUI Objects in Android Software
Static Reference Analysis for GUI Objects in Android SoftwareStatic Reference Analysis for GUI Objects in Android Software
Static Reference Analysis for GUI Objects in Android Software
 
MOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app developmentMOPCON 2014 - Best software architecture in app development
MOPCON 2014 - Best software architecture in app development
 
Building Mobile Applications with Ionic
Building Mobile Applications with IonicBuilding Mobile Applications with Ionic
Building Mobile Applications with Ionic
 
iOS Beginners Lesson 4
iOS Beginners Lesson 4iOS Beginners Lesson 4
iOS Beginners Lesson 4
 
Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4Ionic으로 모바일앱 만들기 #4
Ionic으로 모바일앱 만들기 #4
 
I os 11
I os 11I os 11
I os 11
 
Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月Ruby motion勉強会 2012年7月
Ruby motion勉強会 2012年7月
 
Ionic bbl le 19 février 2015
Ionic bbl le 19 février 2015Ionic bbl le 19 février 2015
Ionic bbl le 19 février 2015
 
Lightning Components Workshop
Lightning Components WorkshopLightning Components Workshop
Lightning Components Workshop
 
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефонаКурсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
Курсы по мобильной разработке под iOS. 4 лекция. Возможности телефона
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web Developers
 
Implement angular calendar component how to drag &amp; create events
Implement angular calendar component how to drag &amp; create eventsImplement angular calendar component how to drag &amp; create events
Implement angular calendar component how to drag &amp; create events
 
iOS Training Session-3
iOS Training Session-3iOS Training Session-3
iOS Training Session-3
 
Android programming basics
Android programming basicsAndroid programming basics
Android programming basics
 
Lightning Components Workshop
Lightning Components WorkshopLightning Components Workshop
Lightning Components Workshop
 
Apple Templates Considered Harmful
Apple Templates Considered HarmfulApple Templates Considered Harmful
Apple Templates Considered Harmful
 

Plus de Peter Friese

Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsPeter Friese
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopPeter Friese
 
Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsPeter Friese
 
Firebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroesFirebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroesPeter Friese
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift LeedsPeter Friese
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in SwiftPeter Friese
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple DevelopersPeter Friese
 
Building Apps with SwiftUI and Firebase
Building Apps with SwiftUI and FirebaseBuilding Apps with SwiftUI and Firebase
Building Apps with SwiftUI and FirebasePeter Friese
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebasePeter Friese
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebasePeter Friese
 
6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase AuthPeter Friese
 
Five Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase AuthFive Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase AuthPeter Friese
 
Building High-Quality Apps for Google Assistant
Building High-Quality Apps for Google AssistantBuilding High-Quality Apps for Google Assistant
Building High-Quality Apps for Google AssistantPeter Friese
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google Peter Friese
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GooglePeter Friese
 
What's new in Android Wear 2.0
What's new in Android Wear 2.0What's new in Android Wear 2.0
What's new in Android Wear 2.0Peter Friese
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinPeter Friese
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android WearPeter Friese
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services RockPeter Friese
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android WearPeter Friese
 

Plus de Peter Friese (20)

Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
 
Building Reusable SwiftUI Components
Building Reusable SwiftUI ComponentsBuilding Reusable SwiftUI Components
Building Reusable SwiftUI Components
 
Firebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroesFirebase for Apple Developers - SwiftHeroes
Firebase for Apple Developers - SwiftHeroes
 
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 +  = ❤️ (Firebase for Apple Developers) at Swift Leeds
 
async/await in Swift
async/await in Swiftasync/await in Swift
async/await in Swift
 
Firebase for Apple Developers
Firebase for Apple DevelopersFirebase for Apple Developers
Firebase for Apple Developers
 
Building Apps with SwiftUI and Firebase
Building Apps with SwiftUI and FirebaseBuilding Apps with SwiftUI and Firebase
Building Apps with SwiftUI and Firebase
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
 
Rapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and FirebaseRapid Application Development with SwiftUI and Firebase
Rapid Application Development with SwiftUI and Firebase
 
6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth6 Things You Didn't Know About Firebase Auth
6 Things You Didn't Know About Firebase Auth
 
Five Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase AuthFive Things You Didn't Know About Firebase Auth
Five Things You Didn't Know About Firebase Auth
 
Building High-Quality Apps for Google Assistant
Building High-Quality Apps for Google AssistantBuilding High-Quality Apps for Google Assistant
Building High-Quality Apps for Google Assistant
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
 
Building Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on GoogleBuilding Conversational Experiences with Actions on Google
Building Conversational Experiences with Actions on Google
 
What's new in Android Wear 2.0
What's new in Android Wear 2.0What's new in Android Wear 2.0
What's new in Android Wear 2.0
 
Google Fit, Android Wear & Xamarin
Google Fit, Android Wear & XamarinGoogle Fit, Android Wear & Xamarin
Google Fit, Android Wear & Xamarin
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 
Google Play Services Rock
Google Play Services RockGoogle Play Services Rock
Google Play Services Rock
 
Introduction to Android Wear
Introduction to Android WearIntroduction to Android Wear
Introduction to Android Wear
 

Dernier

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxOnBoard
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 

Dernier (20)

My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Maximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptxMaximizing Board Effectiveness 2024 Webinar.pptx
Maximizing Board Effectiveness 2024 Webinar.pptx
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 

Model Driven App Development for iPhone and Android

  • 1. Model Driven App Development @peterfriese | @itemismobile http://peterfriese.de | http://mobile.itemis.de for iPhone and Android
  • 3.
  • 5. How to be Awesome?
  • 6. How to be Awesome? Time to Market Happy Users Precision.Great Ideas
  • 7. How to be Awesome? Time to Market Happy Users Precision.Great Ideas Great Ideas
  • 8. How to be Awesome? Time to Market Happy Users Great Ideas Precision.
  • 9. How to be Awesome? Happy Users Precision.Great Ideas Time to Market
  • 10. How to be Awesome? Time to Market Precision.Great Ideas Happy Users
  • 11. There Are 4 Things That Keep Us From Being Awesome Accidental Complexity Wrong Level of Abstraction Ugly Design Boring Code
  • 12. There Are 4 Things That Keep Us From Being Awesome Accidental Complexity Wrong Level of Abstraction Ugly Design Boring Code
  • 13. There Are 4 Things That Keep Us From Being Awesome Wrong Level of Abstraction Ugly Design Boring Code Accidental Complexity
  • 14. There Are 4 Things That Keep Us From Being Awesome Ugly Design Boring Code Accidental Complexity Wrong Level of Abstraction
  • 15. There Are 4 Things That Keep Us From Being Awesome Boring Code Accidental Complexity Wrong Level of Abstraction Ugly Design
  • 16. Oh, did I mention
  • 17. Oh, did I mention Bugs Redundancy Multi- Platform
  • 19. Challenges vs. Threats Time to Market Happy Users Precision.Great Ideas Accidental Complexity Wrong Level of Abstraction Ugly Design Boring Code not in this talk not in this talk
  • 23. Why? ... is code so boring (at times)? ... is there so much accidental complexity? ... is there so much redundancy? ... is our code so buggy?
  • 24. Wrong Level of Abstraction! ... is code so boring (at times)? ... is there so much accidental complexity? ... is there so much redundancy? ... is our code so buggy?
  • 25. Software artifact Anatomy of Modern Software
  • 27. schematic code (manually written) Libraries Frameworks manually written code Anatomy of Modern Software
  • 29.
  • 30. Text
  • 37. tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } }
  • 38. tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } } -(UIViewController*)createController { ! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease]; ! UITabBarController *result = [[UITabBarController alloc] init]; ! NSMutableArray *controllers = [NSMutableArray array]; ! ! UIViewController<IPUIView> *controller; ! UINavigationController *navController; ! IPContentProvider *contentProvider; ! // controller for @"Tuesday" ! contentProvider = [providers providerForSessionsByDay: @"0"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Tuesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Wednesday" ! contentProvider = [providers providerForSessionsByDay: @"1"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Wednesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Thursday" ! contentProvider = [providers providerForSessionsByDay: @"2"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Thursday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Speakers" ! contentProvider = [providers providerForAllSpeakers]; ! ! controller = [[SpeakersListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Speakers"; ! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! result.viewControllers = controllers; ! return result; }
  • 39. tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } } -(UIViewController*)createController { ! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease]; ! UITabBarController *result = [[UITabBarController alloc] init]; ! NSMutableArray *controllers = [NSMutableArray array]; ! ! UIViewController<IPUIView> *controller; ! UINavigationController *navController; ! IPContentProvider *contentProvider; ! // controller for @"Tuesday" ! contentProvider = [providers providerForSessionsByDay: @"0"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Tuesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Wednesday" ! contentProvider = [providers providerForSessionsByDay: @"1"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Wednesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Thursday" ! contentProvider = [providers providerForSessionsByDay: @"2"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Thursday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Speakers" ! contentProvider = [providers providerForAllSpeakers]; ! ! controller = [[SpeakersListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Speakers"; ! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! result.viewControllers = controllers; ! return result; }
  • 40. tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } } -(UIViewController*)createController { ! itemisAppProviders *providers = [[[itemisAppProviders alloc] init] autorelease]; ! UITabBarController *result = [[UITabBarController alloc] init]; ! NSMutableArray *controllers = [NSMutableArray array]; ! ! UIViewController<IPUIView> *controller; ! UINavigationController *navController; ! IPContentProvider *contentProvider; ! // controller for @"Tuesday" ! contentProvider = [providers providerForSessionsByDay: @"0"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Tuesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Wednesday" ! contentProvider = [providers providerForSessionsByDay: @"1"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Wednesday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Thursday" ! contentProvider = [providers providerForSessionsByDay: @"2"]; ! ! controller = [[SessionListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Thursday"; ! controller.tabBarItem.image = [UIImage imageNamed:@"calendar.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! ! // controller for @"Speakers" ! contentProvider = [providers providerForAllSpeakers]; ! ! controller = [[SpeakersListViewController alloc] init]; ! [controller setContentProvider: contentProvider]; ! controller.tabBarItem.title = @"Speakers"; ! controller.tabBarItem.image = [UIImage imageNamed:@"person.png"]; ! navController = [[UINavigationController alloc] initWithRootViewController:controller]; ! [controllers addObject: navController]; ! [controller release]; ! [navController release]; ! result.viewControllers = controllers; ! return result; } 135
  • 43. «DEFINE moduleFile FOR Application» «FILE filenameApplicationDelegateModule()» #import "«filenameApplicationDelegateHeader()»" #import "IPUIView.h" #import "«filenameCentralProvidersHeader()»" «EXPAND importStatements-» @implementation «applicationDelegateClassname()» @synthesize window, rootController; -(UIViewController*)createController { «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease]; UITabBarController *result = [[UITabBarController alloc] init]; NSMutableArray *controllers = [NSMutableArray array]; UIViewController<IPUIView> *controller; UINavigationController *navController; IPContentProvider *contentProvider; «EXPAND barControllerInstance FOREACH buttons» result.viewControllers = controllers; return result; } - (void)applicationDidFinishLaunching:(UIApplication *)application { self.rootController = [self createController]; [window addSubview: [self.rootController view]]; [window makeKeyAndVisible]; } - (void)dealloc { self.rootController = nil; [window release]; [super dealloc]; } @end «ENDFILE» «ENDDEFINE»
  • 44. «DEFINE moduleFile FOR Application» «FILE filenameApplicationDelegateModule()» #import "«filenameApplicationDelegateHeader()»" #import "IPUIView.h" #import "«filenameCentralProvidersHeader()»" «EXPAND importStatements-» @implementation «applicationDelegateClassname()» @synthesize window, rootController; -(UIViewController*)createController { «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease]; UITabBarController *result = [[UITabBarController alloc] init]; NSMutableArray *controllers = [NSMutableArray array]; UIViewController<IPUIView> *controller; UINavigationController *navController; IPContentProvider *contentProvider; «EXPAND barControllerInstance FOREACH buttons» result.viewControllers = controllers; return result; } - (void)applicationDidFinishLaunching:(UIApplication *)application { self.rootController = [self createController]; [window addSubview: [self.rootController view]]; [window makeKeyAndVisible]; } - (void)dealloc { self.rootController = nil; [window release]; [super dealloc]; } @end «ENDFILE» «ENDDEFINE» tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } }
  • 45. «DEFINE moduleFile FOR Application» «FILE filenameApplicationDelegateModule()» #import "«filenameApplicationDelegateHeader()»" #import "IPUIView.h" #import "«filenameCentralProvidersHeader()»" «EXPAND importStatements-» @implementation «applicationDelegateClassname()» @synthesize window, rootController; -(UIViewController*)createController { «centralProvidersClassName()» *providers = [[[«centralProvidersClassName()» alloc] init] autorelease]; UITabBarController *result = [[UITabBarController alloc] init]; NSMutableArray *controllers = [NSMutableArray array]; UIViewController<IPUIView> *controller; UINavigationController *navController; IPContentProvider *contentProvider; «EXPAND barControllerInstance FOREACH buttons» result.viewControllers = controllers; return result; } - (void)applicationDidFinishLaunching:(UIApplication *)application { self.rootController = [self createController]; [window addSubview: [self.rootController view]]; [window makeKeyAndVisible]; } - (void)dealloc { self.rootController = nil; [window release]; [super dealloc]; } @end «ENDFILE» «ENDDEFINE» tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } }
  • 46. «DEFINE barControllerInstance FOR TabbarButton» «IF view.provider != null» // controller for «this.title.expression('', '')» contentProvider = «view.provider.contentProvider('providers', '', '')»; «ENDIF» controller = [[«view.view.className()» alloc] init]; [controller setContentProvider: contentProvider]; controller.tabBarItem.title = «title.expression('', '')»; controller.tabBarItem.image = [UIImage imageNamed:«this.icon.expression('','')»]; navController = [[UINavigationController alloc] initWithRootViewController:controller]; [controllers addObject: navController]; [controller release]; [navController release]; «ENDDEFINE» tabbarApplication itemisApp { button { title= "Tuesday" icon= "calendar.png" view= SessionList( SessionsByDay("0") ) } button { title= "Wednesday" icon= "calendar.png" view= SessionList( SessionsByDay("1") ) } button { title= "Thursday" icon= "calendar.png" view= SessionList( SessionsByDay("2") ) } button { title= "Speakers" icon= "person.png" view= SpeakersList( AllSpeakers() ) } }
  • 50. DEMO
  • 52. SourceUI (Apple TV) iPhone App iPad App Apple TV App UI (iPad) UI (iPhone) @mschluepmann:
  • 53. iPhone App iPad App TV App @APPlauseDSL: APPlause DSL Program APPlause DSL
  • 54. DEMO
  • 55. code Open source - EPL 1.0 code.google.com/p/applause/
  • 56. ‣ Showcase about conferences ‣ Tighter integration with Xcode ‣ Improved Android Generator ‣ Support for BlackBerry ‣ Support for Windows Phone 7 ‣ Support for TV sets? APPlause - Roadmap
  • 57.