Mihai petrescu maad

327 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
327
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
3
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Mihai petrescu maad

  1. 1. Native development process or 3rd party solution?
  2. 2. Pros/Cons User necessary skill set Time required Tools needed Resources available Maintenance UpdatesBackend data and other tools Fragmentation
  3. 3. Native Code public class MainActivity extends FragmentActivity{ public AddUserDialog addUserDialog; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout mainLayout = new LinearLayout(this); mainLayout.setId(R.id.mainWidget); mainLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); mainLayout.setOrientation(LinearLayout.VERTICAL); LinearLayout topLayout = new LinearLayout(this); topLayout.setId(R.id.topWidget); topLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); topLayout.setOrientation(LinearLayout.HORIZONTAL); final float scale = this.getResources().getDisplayMetrics().density; final int pixels = (int) (44 * scale + 0.5f); RelativeLayout navBarRelativeLayout = new RelativeLayout(this); navBarRelativeLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, pixels)); navBarRelativeLayout.setBackgroundColor(0xff999999); Button addUser = new Button(this); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.CENTER_VERTICAL); addUser.setLayoutParams(params); params = null; addUser.setText("Add User"); addUser.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { addUserDialog = new AddUserDialog(MainActivity.this); addUserDialog.show(); } }); navBarRelativeLayout.addView(addUser); mainLayout.addView(navBarRelativeLayout); mainLayout.addView(topLayout); ListViewFragment listViewFragment = new ListViewFragment(); getSupportFragmentManager().beginTransaction().add(R.id.topWidget, listViewFragment, "listViewFragment").commit(); WebViewFragment webViewFragment = new WebViewFragment(); getSupportFragmentManager().beginTransaction().add(R.id.topWidget, webViewFragment, "webViewFragment").commit(); MapViewFragment mapViewFragment = new MapViewFragment(); getSupportFragmentManager().beginTransaction().add(R.id.mainWidget, mapViewFragment, "mapViewFragment").commit(); setContentView(mainLayout); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); Log.d("test", requestCode+""); Log.d("test", resultCode+""); Log.d("test", data+""); if(requestCode == 112 && resultCode == RESULT_OK) if(data.getParcelableExtra("location") != null) addUserDialog.updateDisplay((LatLng) data.getParcelableExtra("location")); } }
  4. 4. Appscend (Native) Code <?xml version="1.0" encoding="UTF-8"?> <par> <cfg> <vt>wd</vt> <avi>home</avi> <dvs>yes</dvs> </cfg> <es> <e> <padlx>0</padlx> <padly>0</padly> <padlw>300</padlw> <padlh>300</padlh> <vt>l</vt> <px>listview.xml.php</px> </e> <e> <padlx>300</padlx> <padly>0</padly> <padlw>724</padlw> <padlh>300</padlh> <vt>w</vt> <px>webview.xml.php</px> <navz>webview</navz> <nav>yes</nav> </e> <e> <padlx>0</padlx> <padly>300</padly> <padlw>1024</padlw> <padlh>424</padlh> <vt>m</vt> <px>mapview.xml.php</px> <navz>mapview</navz> <nav>yes</nav> </e> </es> <b> <p>ln</p> <t>Add User</t> <br>yes</br> <a>m:</a> <pr>addUser.xml.php</pr> </b> </par>
  5. 5. Complex and native apps with Appcelerator via Javascript code VsLightweight apps with PhoneGap via HTML5, CSS & Javascript
  6. 6. Appcelerator:• Learn a new programming language• Limited functionality because of the JavaScript callbackPhoneGap• Non-native apps• Limited functionality and compatibility because the apps are not running native code
  7. 7. An innovative and dynamic RAD platform Native running apps Backend services Mobile marketing solution
  8. 8. • Visual interface for rapid development• IgniteMarkup – development language• Targeted Push Notifications• Cloud based Content Management System• Analytics & User segmentation• Connected Ad-Server, IAP• Deployment over iOS & Android
  9. 9. • Keep native feeling of the apps• Both Android and iOS must have the same functionality• Bug free apps• Easy to implement and modify apps• We take care of fragmentation
  10. 10. • Native feeling on Android = Easter eggs• Take something good, popular and port it• Discover the limits imposed by Android OS and it’s numerous devices and custom ROMs• Scale apps the right way• Memory management
  11. 11. • Activities cannot coexist -> FragmentActivity -> FragmentManager with Fragments ->• Work with ViewGroups for minimum memory fingerprint• MapView from Android Google Maps API v2 requires OpenGL 2.0 for know so all the apps need to have a permission which reduces the availability of the app
  12. 12. • Android is a very powerful OS• Only basic functionality offered• For complex or slightly different approaches classes have to be extended and basic functionality rewritten• Many bugs are still hidden all over and many more appear with each update• API isn’t very well documented• Time and patience is of the essence
  13. 13. Our development process
  14. 14. BOOL useSentinel = (delegate.sentinelController != nil && !delegate.forceSelfNavigation); // NavigateGenericNavbarViewController *target = if (navigationType == kAPSNavigationTypePush) [target pushViewController:newView animated:(pa==0)];useSentinel?(GenericNavbarViewController*)delegate.sentinelController:(GenericNavbarViewController*)delegate.navController; else if (navigationType == kAPSNavigationTypeReplace) [target replaceTopViewController:newView]; if (useSentinel) navigationType = kAPSNavigationTypeReplaceAll; else [target setViewControllers:[NSArray arrayWithObjects:newView,nil] animated:(pa==0)];NSString *viewType;if (appDelegate.deviceIsIPad && [parsedConfigs objectForKey:@"padvt"] && !delegate.forceSelfNavigation) viewType = // End animation[parsedConfigs objectForKey:@"padvt"]; switch (pa) {else viewType = [parsedConfigs objectForKey:@"vt"]; case 1: case 2: case 3: case 4: [UIView commitAnimations];GenericViewController *newView = break;(GenericViewController*)[UtilitiesClass getViewControllerOfType:viewType withParams:request.resource withTitle:nil withIcon:nil withNavController:targetwithTabController:delegate.tabController]; case 5: if (navigationType != kAPSNavigationTypeReplace) newView.parent = delegate; [target.view popIn:.5 delegate:nil]; else newView.parent = delegate.parent; break;newView.configs = parsedConfigs; case 6: newView.paramXml = request.resource; [target.view fallIn:.5 delegate:nil]; if (configModifiers) newView.configModifiers = configModifiers; if (delegate.forceSelfNavigation) newView.sentinelController = delegate.sentinelController; break; delegate.forceSelfNavigation = NO; case 7: [target.view fadeIn:.5 delegate:nil]; if ([parsedConfigs objectForKey:@"lcst"]) newView.shouldLoadElements = YES; break; case 8: newView.elements = [result objectForKey:@"e"]; newView.buttons = [result objectForKey:@"b"]; [glview prepareTextureTo:target.view]; newView.actions = [result objectForKey:@"la"]; [glview setClearColorRed:0.0 green:0.0 blue:0.0 alpha:1.0]; newView.sections = [result objectForKey:@"s"]; [glview startTransition]; newView.menuElements = [result objectForKey:@"me"]; break; if ([[result objectForKey:@"et"] count] > 0) newView.elementTemplate = [[result objectForKey:@"et"] objectAtIndex:0]; case 10: case 20: case 30: case 40: if (request.data) newView.attachedRequestData = [[request.data copy] autorelease]; newView.locationRequestData = request.sendLocation; [UIView commitAnimations]; newView.locationRequestAccuracy = request.accuracy; break; if (useSentinel) newView.isWidget = YES; case 50: [transitionView popIn:.5 delegate:nil];newView.page = delegate.selectedItem; break;if (delegate.selectedItem != -1 && delegate.selectedItem < [delegate.elements count]) newView.parentElement =[delegate.elements objectAtIndex:delegate.selectedItem]; case 60: NSDictionary *passData = [delegate passData]; [transitionView fallIn:.5 delegate:nil]; if (passData) newView.passedData = passData; break; case 70: NSMutableArray *genericAction = [result objectForKey:@"ga"]; [transitionView fadeIn:.5 delegate:nil];if ([genericAction count] > 0) newView.genericAction = [UtilitiesClass actionFromDictionary:[genericAction objectAtIndex:0]]; break;int pa = [animation length] != 0 ? [animation intValue] : [delegate.configs objectForKey:@"pa"] ? default:[[delegate.configs objectForKey:@"pa"] intValue] : 0; break; } if (navigationType != kAPSNavigationTypeModal) { } NSObject<EPGLTransitionViewDelegate> *transition; else { EPGLTransitionView *glview; UINavigationController *nController = [UINavigationController alloc]; UIView *transitionView; for (UIView *view in [target.view subviews]) if (![view isKindOfClass:[UINavigationBar class]] && ![view isKindOfClass:[UIToolbar class]] newView.navController = nController;&& !view.hidden) transitionView = view; newView.isModal = YES; // Start animation switch (pa) { [[nController initWithRootViewController:newView] autorelease]; case 1: case 2: case 3: case 4: [UIView beginAnimations:nil context:nil]; //if ([nController respondsToSelector:@selector(modalTransitionStyle)]) nController.modalTransitionStyle = [UIView setAnimationTransition:pa forView:target.view cache:YES]; UIModalTransitionStyleCrossDissolve; [UIView setAnimationDuration:.5]; break; nController.modalPresentationStyle = modalPresentation; case 8: nController.view.frame = CGRectMake(0, 0, appDelegate.mainWidth, appDelegate.mainHeight); transition = [[[FlipForward alloc] init] autorelease]; glview = [[[EPGLTransitionView alloc] initWithView:target.view delegate:transition] autorelease]; if (appDelegate.visiblePopover) { break; [appDelegate.visiblePopover dismissPopoverAnimated:NO]; case 10: case 20: case 30: case 40: [UIView beginAnimations:nil context:nil]; [appDelegate.visiblePopover.delegate popoverControllerDidDismissPopover:appDelegate.visiblePopover]; [UIView setAnimationTransition:(pa/10) forView:transitionView cache:YES]; } [UIView setAnimationDuration:.5]; break; [target presentModalViewController:nController animated:YES]; default: } break; } [self cleanup];
  15. 15. newView.putSerializable("configs", parsedConfigs);public final static int kAPSNavigationTypePush=1; newView.putString("parentAvi" , ((GenericViewController)delegate).avi); public final static int kAPSNavigationTypeModal=2; newView.putString("paramXml" , request.resource); public final static int kAPSNavigationTypeReplace=3; if (configModifiers != null) newView.putSerializable("configModifiers", configModifiers); public final static int AnimDefaultPush = 0; public final static int AnimDefaultReplace = -1; if (parsedConfigs.get("lcst") != null) newView.putBoolean("shouldLoadElements", true); public final static int AnimDefaultModal = -2; public final static int AnimNone = -99; newView.putSerializable("elements", UtilitiesClass.getWrapper(result, "e")); newView.putSerializable("buttons", UtilitiesClass.getWrapper(result, "b"));public Object delegate;public DataRequest request = null; newView.putSerializable("actions", UtilitiesClass.getWrapper(result, "la"));boolean started = false; newView.putSerializable("sections", UtilitiesClass.getWrapper(result, "s"));boolean forceMaster = false; if (UtilitiesClass.getWrapper(result, "et") != null && UtilitiesClass.getWrapper(result, "et").size() > 0)HashMap<String, Object> configModifiers = null; newView.putSerializable("elementTemplate", UtilitiesClass.getWrapper(result, "et").get(0));String animation; if (request.data != null) newView.putSerializable("attachedRequestData", request.data);int navigationType = kAPSNavigationTypePush; newView.putBoolean("locationRequestData", request.sendLocation); newView.putInt("locationRequestAccuracy", request.accuracy);public void navigate(){ newView.putInt("page", ((GenericViewController)delegate).selectedItem); if (started) return; UtilitiesClass.DebugLog("Request to navigate to path " + request.resource); if (((GenericViewController)delegate).selectedItem != -1 && ((GenericViewController)delegate).selectedItem < new DataSource(this, request); ((GenericViewController)delegate).elements.size()) newView.putSerializable("parentElement",} ((GenericViewController)delegate).elements.get(((GenericViewController)delegate).selectedItem)); HashMap<String, Object> passData = ((GenericViewController)delegate).passData();public void modal(){ if (started) return; if (passData!= null){ newView.putSerializable("passedData", passData); passData = null;}UtilitiesClass.DebugLog("Request for modal view with path " + request.resource); navigationType = kAPSNavigationTypeModal; ArrayList<HashMap<String, Object>> genericAction = UtilitiesClass.getWrapper(result, "ga"); new DataSource(this, request); try {} if (genericAction != null && genericAction.size() > 0)public void replace(){ newView.putString("genericAction", ObjectSerializer.serialize(new ActionManager().actionFromDictionary(genericAction.get(0)))); if (started) return; } catch (IOException e) { UtilitiesClass.DebugLog("Request to replace current view with view at path " + request.resource); e.printStackTrace(); navigationType = kAPSNavigationTypeReplace; new DataSource(this, request); }} int pa;public void cleanup() { if (request != null) { request = null; } if (animation != null) { animation = null; } Fragment newFragment = UtilitiesClass.getViewControllerOfType(viewType, request.resource); if (configModifiers != null) { configModifiers = null; } newFragment.setArguments(newView); started = false; navigationType = kAPSNavigationTypePush; if (navigationType == kAPSNavigationTypePush){ forceMaster = false;} pa = animation.length() != 0 ? Integer.parseInt(animation) : ((GenericViewController)delegate).configs.get("pa") != null ? GenericViewController.getInteger(((GenericViewController)delegate).configs, "pa") : AnimDefaultPush;public void dataLoaded(String XMLContents) { //((GenericViewController)delegate).parentActivity.push(newFragment);//AppBuilderAppDelegate *appDelegate = (AppBuilderAppDelegate *)[[UIApplication sharedApplication] delegate]; ((GenericViewController)delegate).parentActivity.push(newFragment, ((GenericViewController)delegate).avi);HashMap<String, Object> result = new XMLGetter().XMLParse(XMLContents, new ArrayList<String>(Arrays.asList("e", "b", "cfg", "la", "ga", "s", "et"))); } else if (navigationType == kAPSNavigationTypeReplace) {if(result!= null){ pa = animation.length() != 0 ? Integer.parseInt(animation) : ((GenericViewController)delegate).configs.get("pa") != null ?UtilitiesClass.DebugLog("Interpreted received data: " + result.keySet()); GenericViewController.getInteger(((GenericViewController)delegate).configs, "pa") : AnimDefaultReplace; ((GenericViewController)delegate).parentActivity.replace(newFragment, ((GenericViewController)delegate).avi);if (UtilitiesClass.getWrapper(result, "cfg").size() == 0) {UtilitiesClass.DebugLog("No view configuration found, attempting to execute launch actions..."); } else if (navigationType == kAPSNavigationTypeModal) {for (HashMap<String, Object> action : UtilitiesClass.getWrapper(result, "la")){ newView.putBoolean("isModal", true);ActionManager newAction = new ActionManager(); ((GenericViewController)delegate).parentActivity.modal(newFragment, ((GenericViewController)delegate).avi);newAction.performAction(newAction.actionFromDictionary(action),delegate);newAction = null;} }cleanup();return; cleanup();} } else {HashMap<String, Object> parsedConfigs = UtilitiesClass.getWrapper(result, "cfg").get(0); Toast.makeText(((GenericViewController)delegate).parentActivity, "Error parsing file, perhaps unclosed tags!", Toast.LENGTH_LONG).show(); }if (configModifiers != null) for (HashMap.Entry<String, Object> entry : configModifiers.entrySet()) parsedConfigs.put(entry.g etKey(), entry.getValue()); }/*GenericViewController target; if (delegate.isMaster && !forceMaster) target=[(SplitViewController *)delegate.splitRoot splitDetails]; public void failed() {else target = (GenericNavbarViewController*)delegate.navController;*/ cleanup(); Toast.makeText(((GenericViewController)delegate).parentActivity, "Network error!", Toast.LENGTH_SHORT).show();String viewType; }if (GlobalSettings.deviceIsTablet && parsedConfigs.get("padvt") != null && !forceMaster) viewType = GenericViewController.getString(parsedConfigs, "padvt");else viewType = GenericViewController.getString(parsedConfigs, "vt");Bundle newView = new Bundle();
  16. 16. MKCoordinateSpan locationSpan;-(void) configureChild { NSArray *components; locationSpan.latitudeDelta = upper.latitude - lower.latitude; mapIsLocationSelector = [[configs objectForKey:@"selector"] isEqualToString:@"yes"]; locationSpan.longitudeDelta = upper.longitude - lower.longitude; if (spotElements) [spotElements release]; CLLocationCoordinate2D locationCenter; spotElements = [[NSMutableArray alloc] initWithArray:[self placesFromElements]]; locationCenter.latitude = (upper.latitude + lower.latitude) / 2; if (locationManager) { locationCenter.longitude = (upper.longitude + lower.longitude) / 2; locationManager.delegate = nil; [locationManager release]; } MKCoordinateRegion region = MKCoordinateRegionMake(locationCenter, locationSpan); // Initialize location service, dont start updates return region; locationManager=[[CLLocationManager alloc] init]; locationManager.delegate=self; } locationManager.desiredAccuracy=[configs objectForKey:@"acr"]!=nil?[[configs objectForKey:@"acr"] doubleValue]:0; // Map initial location - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { if ([elements count]) { if ([[configs objectForKey:@"fit"] isEqualToString:@"yes"]) [map setRegion:[self regionFromLocations:spotElements] if ( mapView.userLocation == annotation ) {animated:YES]; else { return nil; // display default image CLLocationCoordinate2D location; } MKCoordinateSpan span; static NSString *viewIdentifier = @"annotationView"; if ([configs objectForKey:@"il"]!=nil) { MKAnnotationView *annotationView; components = [[configs objectForKey:@"il"] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ,"]]; if (mapIsLocationSelector) { location.latitude = [[components objectAtIndex:0] doubleValue]; annotationView = (DraggableAnnotationView *) [map dequeueReusableAnnotationViewWithIdentifier:viewIdentifier]; location.longitude = [[components objectAtIndex:1] doubleValue]; if (annotationView == nil) annotationView = [[[DraggableAnnotationView alloc] initWithAnnotation:annotation } reuseIdentifier:viewIdentifier] autorelease]; else { location.latitude = 0; annotationView.draggable = YES; location.longitude = 0; } [(DraggableAnnotationView*)annotationView setDelegate:self]; [(DraggableAnnotationView*)annotationView setMapView:map]; if ([configs objectForKey:@"is"]!=nil) { } span.latitudeDelta = [[configs objectForKey:@"is"] doubleValue]; else { span.longitudeDelta = [[configs objectForKey:@"is"] doubleValue]; annotationView = (MovableAnnotationView *) [map dequeueReusableAnnotationViewWithIdentifier:viewIdentifier]; }else { if (annotationView == nil) annotationView = [[[MovableAnnotationView alloc] initWithAnnotation:annotation span.latitudeDelta=.05; reuseIdentifier:viewIdentifier] autorelease]; [(MovableAnnotationView*)annotationView setMapView:map]; span.longitudeDelta=.05; } } MKCoordinateRegion region; region.center = location; Placemark *spot = (Placemark*)annotation; region.span=span; NSDictionary *current = [elements objectAtIndex:spot.index]; [map setRegion:region animated:YES]; } } UIImageView *pinImageView = [[[UIImageView alloc] init] autorelease]; else if (!mapIsLocationSelector) [self alert:@"Nothing to display!"]; // Map configurations map.mapType = [configs objectForKey:@"mt"]!=nil?[[configs objectForKey:@"mt"] intValue]:2; annotationView.frame = CGRectMake(0, 0, [current objectForKey:@"pisw"]?[[current objectForKey:@"pisw"] intValue]:[configs if ([[configs objectForKey:@"ze"] isEqualToString:@"no"]) map.zoomEnabled = NO; objectForKey:@"pisw"]?[[configs objectForKey:@"pisw"] intValue]:40, [current objectForKey:@"pish"]?[[current objectForKey:@"pish"] if ([[configs objectForKey:@"se"] isEqualToString:@"no"]) map.scrollEnabled = NO; if ([[configs objectForKey:@"tu"] isEqualToString:@"yes"]) [self track]; intValue]:[configs objectForKey:@"pish"]?[[configs objectForKey:@"pish"] intValue]:40); else if (([[configs objectForKey:@"ul"] isEqualToString:@"yes"]) || (mapIsLocationSelector && [[configs objectForKey:@"il"] isEqualToString:@"0,0"])) { [self trackonce]; annotationView.canShowCallout = YES; [self sloc]; pinImageView.frame = annotationView.frame; } pinImageView.clipsToBounds = YES; // Add locations [map addAnnotations:spotElements]; [appDelegate.imageManager getImageFromURL:[current objectForKey:@"pin"]!=nil?[current objectForKey:@"pin"]:[configs if (mapIsLocationSelector) [map selectAnnotation:selectionMarker animated:NO]; objectForKey:@"pin"]!=nil?[configs objectForKey:@"pin"]:@"pinRed.png" inView:pinImageView [spotElements release];} ofSize:CGSizeMake(pinImageView.frame.size.width, pinImageView.frame.size.height) cornerRadius:[current objectForKey:@"pir"]?[[current- (NSArray*)placesFromElements { objectForKey:@"pir"] intValue]:[configs objectForKey:@"pir"]?[[configs objectForKey:@"pir"] intValue]:0 contentMode:[current NSMutableArray *sElements = [[[NSMutableArray alloc] initWithCapacity:1] autorelease]; objectForKey:@"picm"]!=nil?[current objectForKey:@"picm"]:[configs objectForKey:@"picm"]!=nil?[configs objectForKey:@"picm"]:@"aft" Placemark *spot; reflection:NO offset:CGSizeZero activity:YES fadein:YES forceAsync:NO]; if (mapIsLocationSelector) { [elements addObject:[NSDictionary dictionaryWithObjectsAndKeys:[configs objectForKey:@"il"], @"l", @"Hold and drag to position", @"n", nil]]; [annotationView addSubview:pinImageView]; } int i = 0; if ([current objectForKey:@"a"] != nil || [configs objectForKey:@"ga"]) { for (NSDictionary *place in elements) { spot = [[Placemark alloc] initWithCoordinate:[place objectForKey:@"l"] setName:[place objectForKey:@"n"] annotationView.rightCalloutAccessoryView = [UIButtonsetDescription:[place objectForKey:@"d"]]; buttonWithType:UIButtonTypeDetailDisclosure]; spot.index = i++; [sElements addObject:spot]; [(UIButton *)annotationView.rightCalloutAccessoryView addTarget:self [spot release]; } action:@selector(openSpot:) forControlEvents:UIControlEventTouchUpInside]; } if (mapIsLocationSelector) selectionMarker = [[sElements lastObject] retain]; return sElements;} if ([current objectForKey:@"i"] != nil) { UIImageView *imageView = [[[UIImageView alloc] init] autorelease];- (MKCoordinateRegion)regionFromLocations:(NSArray*)sElements { CLLocationCoordinate2D upper = [[sElements objectAtIndex:0] coordinate]; imageView.frame = CGRectMake(0, 0, [[configs objectForKey:@"isw"] CLLocationCoordinate2D lower = [[sElements objectAtIndex:0] coordinate]; intValue], [[configs objectForKey:@"ish"] intValue]); // FIND LIMITS [appDelegate.imageManager getImageFromURL:[current for(Placemark *eachLocation in sElements) { if([eachLocation coordinate].latitude > upper.latitude) upper.latitude = [eachLocation coordinate].latitude; objectForKey:@"i"] inView:imageView ofSize:CGSizeMake([[configs objectForKey:@"isw"] intValue], [[configs objectForKey:@"ish"] intValue]) if([eachLocation coordinate].latitude < lower.latitude) lower.latitude = [eachLocation coordinate].latitude; if([eachLocation coordinate].longitude > upper.longitude) upper.longitude = [eachLocation coordinate].longitude; cornerRadius:[current objectForKey:@"icr"]!=nil?[[current objectForKey:@"icr"] intValue]:[[configs objectForKey:@"icr"] intValue] if([eachLocation coordinate].longitude < lower.longitude) lower.longitude = [eachLocation coordinate].longitude; contentMode:@"afl" reflection:NO offset:CGSizeMake(0, 0) activity:imageShowActivity fadein:imageFadeIn forceAsync:NO]; } annotationView.leftCalloutAccessoryView = imageView; } return annotationView; } }

×