Various topics

Deals with various topics

Dealing with the status bar

To prevent the iOS status bar to impact the viewable/drawable area of the app, each time the iOS status bar is displayed, we have to make room at the top of the page.

  1. Add a vertical box and call it viewareaStatusbar
  • Adjust it's background color to match the app
  • Set it's height to 20px using the margin settings
  • Check the exclude checkbox so that it's excluded by default. In the image below, it's unchecked so that you can still see the viewareaStatusbar
  1. In the i.e. load() method of the page, add a small code snippet
  • We use conditional compilation to add code if we are on iOS. If we are on Android, the viewareaStatusbar will not be visible, as it's excluded by default.
  • We use isStatusBarVisible attribute to check for the status bar, and if it is visible, INCLUDE the viewareaStatusbar to make room for the statusbar
class MainPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		#if(os(iOS))
		let isStatusBarVisible = SCDRuntime.getSystem()!.isStatusBarVisible
		if let cont = self.page!.getWidgetByName("viewareaStatusbar") as! SCDWidgetsContainer? {
			let gd = cont.layoutData as! SCDLayoutGridData	
			gd.isExclude = !isStatusBarVisible
		}
		#endif
	}
}

Persistency

In this chapter, we will describe how to store and retrieve objects in SCADE. First, we need to create a sample class that we want to store.

There are three main requirements for the class to be persisted.

  • a class has to have a default initializer, i.e. "init()". Use override init() {}.
  • properties that have to be persisted need to be defined by "var" and not "let". Immutable properties' values will not be persisted.
  • you need to inherit from EObject

Let's create car class:

import ScadeKit

class Car : EObject {
  
 let manufactorer:String
 let model:String
 let licensePlate:String
	
 override init() {}
  
 init(manufactorer:String, model:String, licensePlate:String) {
   self.manufactorer = manufactorer
   self.model = model
   self.licensePlate = licensePlate
 }
 }

Now let's populate, store and reload it....

class MainPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		saveAndLoadSingleCar()
	}
	
func saveAndLoadSingleCar() {
		
	let merc = Car(manufactorer:"Mercedes",model:"C350", licensePlate:"SCADE R1")
	SCDRuntime.saveDocument("merc1", document: merc)
		
	let mercReloaded = SCDRuntime.loadDocument("merc1") as! Car
	print(mercReloaded)
	}
 }

Let's say you are Jay Leno and want to save your collection of cars, you would create a list and use the same calls for saving and loading. Saving twice overrides the file.

Here our CarCollection

import ScadeKit

class CarCollection : EObject {

  var cars : [Car] = []
  
  override init() {}
  init(cars:[Car]) {
	   self.cars = cars
  }
}

and here the code to save the collection

import ScadeKit

class MainPageAdapter: SCDLatticePageAdapter {

	// page adapter initialization
	override func load(_ path: String) {		
		super.load(path)
		
		saveAndLoadCollection()
	}
	
	func saveAndLoadCollection() {
		let merc = Car(manufactorer:"Mercedes",model:"C350", licensePlate:"SCADE R1")
		let bmw =  Car(manufactorer:"BMW",model:"M5", licensePlate:"ReallyFast")
		
		let collection = CarCollection(cars:[merc,bmw])
		SCDRuntime.saveDocument("lenoscars", document: collection)
		
		let carcollectionReloaded = SCDRuntime.loadDocument("lenoscars") as! CarCollection
		print("Stored \(carcollectionReloaded.cars.count) cars")
	}
	
	func saveAndLoadSingleCar() {
		
		let merc = Car(manufactorer:"Mercedes",model:"C350", licensePlate:"SCADE R1")
		SCDRuntime.saveDocument("merc1", document: merc)
		
		let mercReloaded = SCDRuntime.loadDocument("merc1") as! Car
		print(mercReloaded)
	}
	
}

Working with Timer

You have the following options for using timers

  • Use the timer that comes with SCADE. It's available on all platforms and for all versions of Android and iOS
  • Use the Swift Foundation Timer. Your limitation here is that this timer is only available for iOS 10.x onwards and requires OSX 10.12 onwards, so you need to use a conditional statement and use the old timer for iOS versions < 10 if you want to support iOS 9

To use the SCADE timer, use the SCDRuntime object. This calls the function set in closure every withDelay seconds:

SCDRuntime.call(withDelay:1,closure: { self.doSomething() } )

To use the Swift Foundation timer is straightforward:

let _ : Timer = 
    Timer.scheduledTimer(
       withTimeInterval: 4, 
       repeats: false, 
       block: {timer in print("hello")})

Stackoverflow discusses the backward compatibility issues of timer here http://stackoverflow.com/questions/38695802/timer-scheduledtimer-swift-3-pre-ios-10-compatibility

Accessability