Is your database environment optimized for your applications? We help our clients to switch to Enterprise-grade proactive, expert database management and thus reduce hardware costs. Empower your business critical systems by keeping your databases always available. We provide database consultancy that will help you to enhance the performance and availability of your databases. Our database consultants can suit your needs and are ready to help build schema, administer already created DBs and improve your existing data clusters and can handle large chunks of ‘big data’, easily trumping the biggest RDBMS.

We provide consultancy services for NoSQL databases like CassandraRedis as well as SQL databases. We also offer support services to ensure that your systems are always accustomed to perform at their best. We provide database consultancy that will help you enhance your databases.

When it comes to larger database with enhanced requirements of full text search as well as fast query response, our experts can guide you  the best architecture combining multiple databases to achieve the desired results. We can help you deploy Elastic search with SQL as well as NoSQL databases. With real experience in projects with MongoDB, PostgreSQL, MySQL, SQL Server, Redis, Cassandra, Scylla, Elastic search  you can fully rely on us for your data needs.

Do you have a project in mind?

Get a free consultation

Discuss a Project

Do you want us to build an App for you ?

Page Speed of web page is a measurement or a value of how fast the content on our web page loads. It is the speed in which web pages are downloaded and displayed on the user’s web browser. Page speed can be described in either “page load time” (the time it takes to fully display the content on a specific page) or “time to first byte” (how long it takes for your browser to receive the first byte of information from the web server).

Page Speed depends on following things:

  1. Server Response Time (TTFB)
  2. Poor Web Hosting
  3. Use a CDN (Content distribution network)
  4. Java Script ,CSS resources
  5. Asynchronous of  files
  6. Enable compression
  7. Use Optimized Images
  8. Media Files
  9. Remove unnecessary Plug-in and Script
  10. Leverage browser caching
  11. Reduce JavaScript execution time

1. Server Response Time (TTFB)

It is the time that passes between a client requesting a page in a browser and a server responding to that request. The optimal server response time is under 200ms.

Lack of caching is also the cause in the reduction of Server Response Time because every time browser get files from server rather than from cache. 

To improve your server response time, look for performance bottlenecks like slow database queries, slow routing, or a lack of adequate memory and fix them.

I think don’t waste time on to optimize Server response time because that is related to server side which is not in our control directly. When you fix other issue server response time also decrease with that dramatically

2. Poor Web Hosting

Poor web hosting is a factor that reduce the Server response time. Most new site owners choose the cheapest possible option for hosting. While this is often enough in the beginning, you’ll likely need to upgrade once you start getting more traffic. We have three options for hosting i.e.

  • Shared hosting
  • VPS hosting (Dedicated server)

Shared hosting is the cheapest option and you can often get it for about five dollars per month. With shared hosting, you share certain resources like CPU, disk space, and RAM with other sites hosted on the same server which is not good for google page speed.

With VPS (Virtual Private Server) hosting, you still share a server with other sites, but you have your own dedicated portions of the server’s resources. This is a good in-between option. It protects your site from everyone else on your server without the cost required for dedicated hosting which will increase the page speed because no other traffic comes here.

That is a reason I suggest you to using VPS hosting instead of shared server or poor web hosting because that is main cause in the reduction of Server Response Time. Shared server contains more than one websites which increase the traffic.

3. Use a CDN (Content distribution network)

CDN stands for Content distribution network. It is also known as content delivery network.

A content delivery network (CDN) is a system of distributed servers (network) that deliver pages and other web content to a user, based on the geographic locations of the user, the origin of the webpage and the content delivery server.

Always use CDNs instead of download files of JS or CSS because CDNs are placed closest to the user, it’s possible to reduce latency when the distance that your content needs to travel is shorter. A CDN can make your website load much faster.

4. Java Script and CSS resources

Remove all the unnecessary files either they are CSS or JS or any other (font). And make sure that removal of files don’t affect on page design and functionality.

  • Remove all the unnecessary comments and code that is unused by page.
  • Minimize all the CSS and JS files. It will consume less space and increase page time because it will reduce the size of file. You can dramatically increase your page speed.
  • Remove comments, formatting and unused code from files.
  • If page use more than one JS file then merge all JS file in one. It will decrease JS payload.
  • Avoid using libraries which have their own CSS and scripts because 80% of CSS and script content are not necessary for our work (useless). These libraries take too much time to load.

5. Asynchronous of  files

A browser can load files synchronously as well as asynchronously. When files are synchronous loading, the browser will load one file at a time.

Many times, we use more than one file for styling and script (libraries script) and many in cases files are bulkier than many other page elements and browsers typically take longer to load them.

Load all the Java Script files asynchronously make sure that it don’t affect other functionality in page (animation or anything else). Here below File script1.js load synchronously and script2 and script3 are loaded asynchronously. Asynchronous of files is simply done by

<script src="../script1.js"></script>
<script src="../script2.js" async></script>
<script src="../script3.js" async></script>

Don’t load interlink files asynchronous some time smaller file use larger one. And it gives error because other file not completely loaded. The script.js file contains jquery code but the size of script.js as compared to jquery.min.js is less and it load completely and jquery is still loading which will give error.

<script src="../jquery.min.js" async></script>
<script src="../script.js" async></script>

We can use rel=”preload” to load CSS file asynchronously. Some browser can’t support preload functionality.

<link rel="stylesheet" href"../style1.css" >
<link rel="preload" href"../style2.css" as="style">
<link rel="preload" href"../style3.css" as="style">

Here style1.css is loaded as it is where as style2.css and style3.css preload.

6. Enable compression (GZIP)

When a browser visits a web server it checks to see if the server has compression enabled and requests the web page. If it’s enabled it receives the compression file which is significantly smaller and if it isn’t, it still receives the page, only the uncompressed version which is much larger. Here is the code to enable compression on following web servers.

  • On NGINX web servers
# Load gzip prefrences
gzip on;
gzip_proxied any;
gzip_types application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;
location ~* \.(css|webp|js|ttf|otf|svg)$ {
		expires 365d;
}
  • On Apache web servers
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
  • Via .htaccess
<ifModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file .(html?|txt|css|js|php|pl)$
mod_gzip_item_include handler ^cgi-script$
mod_gzip_item_include mime ^text/.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_exclude mime ^image/.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</ifModule>

7. Use Optimized Images

Use properly sizing images which is a simple way to reduce its loading time. Some time our images are bigger in size which takes too much time. The best way is resized that images by own rather than to use CSS. Alternate way is use “srcset” and “size” attribute for <img> tag i.e.

<img      srcset = "template-880w.jpg 880w , template-480w.jpg 480w , template-320w.jpg 320w"   sizes  = "(max-width:320px) 280px , (max-width:480px) 440px,800px"  src = "template-880w.jpg" >

8. Media files

Media files especially images are also play an important role in speed of web page speed. Media files such as images can be a real drag on your site’s performance. In many ecommerce site large images are used which become a main cause of page speed.

  • Don’t GZIP the image for compression because they aren’t compressed the same way as text files.
  • Use smaller images because larger images take more time to load.  
  • Convert all the images into “.webp” format and Use .webp format as img srcset because .webp load faster as compared to other image formats. But there is one drawback of using  .webp that is safari do not support it therefore use like that
<picture>
	<source srcset="../insta.webp" type="image/webp" data-aos="fade-up">
	<img src="../insta.png"/>
</picture>
<script>
/*	check webp support	*/
function supportsWebp()
{
    if (!self.createImageBitmap) return false;
    const webpData = 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=';
    const blob = fetch(webpData).then(r => r.blob());
    return createImageBitmap(blob).then(() => true, () => false);
}

if(supportsWebp()) 
{
    var root = document.getElementsByTagName( 'html' )[0];
    root.className += ' webp';
}
else 
{
    var root = document.getElementsByTagName( 'html' )[0];
    root.className += ' no-webp';
}
</script>
  • Preload the images make sure that other content can’t disturb with that.
<link rel="preload" href="../image.jpg" as="image" >
<link rel="preload" href="../style.css" as="style" >
<link rel="preload" href="../script.js" as="script">
<link rel="preload" href="../font.woff" as="font"  >
  • In this technique, files are preload and when they are used then content is defined.
  • For Icon use custom icon (own images) rather than to use third party library (font awesome). It consume less time as compared to third party libraries

9. Remove unnecessary Plug-in and Script

We’ve to remove the unnecessary script (unused) and avoid using third party script to resolve that issue. You should do following to reduce the impact of third-party code.
All such plug-in or scripts negatively affect the website speed. Remove unnecessary libraries because they have their own scripts and styling which takes too much time.

  • Defer the loading of JavaScript
  • Use link tags with preconnect attributes

10. Leverage Browser Caching

Caching allows your web server to send a web page at a much faster pace to a browser after it has already been delivered once. To leverage your browser’s caching generally means that you can specify how long web browsers should keep files stored locally. That way the user’s browser will download less data while navigating through your pages, which will improve the loading speed of your website. To enable it, add those lines to your .htaccess file

## EXPIRES CACHING ##
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 2 days"
</IfModule>
## EXPIRES CACHING ##

11. Reduce JavaScript execution time

You won’t have any control over what those external scripts do. Short of not including them, about the only thing you can do is defer their loading. This allows the page to continue to load and execute while the script is loaded and executed later. This method doesn’t work with all scripts, but it will work with most.

<script defer src= ="https://example.com/script.js"></script>

Do you want us to build an App for you ?

Introduction:

VPN App has been developed using IKEV2 protocol the most secure and fast of all the protocols. As android did not have built-in support for IKEV2 protocol so I have used StronSwan (the OpenSource IPsec-based VPN Solution).

Architecture Overview:

The App consists of a Java part, the native strongSwan libraries (libstrongswan, libcharon etc.) and a library to glue these two parts together. The Java part and the libraries communicate by means of the Java Native Interface (JNI).

StrongSwan Configuration:

I am working on windows platform. For configuring StrongSwan there are some shell commands, As windows cmd does not support shell commands for this I have used CENTOS virtual machine. Download VMWare or Vitual box to host your virtual machine on windows and then open .vmx file.

In CENTOS you need the following tools:

  • a recent GNU C compiler (>= 3.x)
  • automake
  • Autoconf
  • Libtool
  • pkg-config
  • gettext
  • perl
  • Python
  • lex/flex
  • yacc/bison
  • gperf

Open terminal window in CENTOS

1. Clone StrongSwan using command:

git clone https://git.strongswan.org/strongswan.git

After a successful check out, give the autotools a try:

2. First go to the strongswan directory that you have cloned by running following command:

cd strongswan/

3. Then run these commands one by one after each command done successful :

•	./autogen.sh
•	./configure
•	Make
•	make install

This creates several pre-built source files.

4. Next go to JNI directory by running the following command:

cd src/frontends/android/app/src/main/jni

And run this command:

Git clone https://git.strongswan.org/android-ndk-boringssl.git -b ndk-staticopenssl

Now copy the code from CENTOS to window and run the app in android studio the code for the App can be found in the source: strongswan/src/frontends/android directory of our repository. To build it the Android SDK and NDK are required.

5. After that we need .so files for native classes to communicate with java classes. Download the Strongswan project from Github and copy JniLibs folder from this github project and paste it in your project that have copied from CENTOS in the following path:

strongswan/src/frontends/android /app/src/main

Try to build the project if there is ndk path problem try replacing this

task buildNative(type: Exec) {
    workingDir 'src/main/jni'
commandLine "${android.ndkDirectory}/ndk-build", '-j', Runtime.runtime.availableProcessors()
}

with this

task buildNative(type: Exec) {
    workingDir 'src/main/jni'
commandLine "${android.ndkDirectory}\ndk-build.cmd", '-j', Runtime.runtime.availableProcessors()
}

and sync now.

6. One last thing
Replace following code from

strongswan\src\frontends\android\app\src\main\java\org\strongswan\android\logic/CharonVpnService.java
SettingsWriter writer = new SettingsWriter();
writer.setValue("global.language", Locale.getDefault().getLanguage());
writer.setValue("global.mtu", mCurrentProfile.getMTU());
writer.setValue("global.nat_keepalive", mCurrentProfile.getNATKeepAlive());
writer.setValue("global.rsa_pss", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_RSA_PSS) != 0);
writer.setValue("global.crl", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_DISABLE_CRL) == 0);
writer.setValue("global.ocsp", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_DISABLE_OCSP) == 0);
writer.setValue("connection.type", mCurrentProfile.getVpnType().getIdentifier());
writer.setValue("connection.server", mCurrentProfile.getGateway());
writer.setValue("connection.port", mCurrentProfile.getPort());
writer.setValue("connection.username", mCurrentProfile.getUsername());
writer.setValue("connection.password", mCurrentProfile.getPassword());
writer.setValue("connection.local_id", mCurrentProfile.getLocalId());
writer.setValue("connection.remote_id", mCurrentProfile.getRemoteId());
writer.setValue("connection.certreq", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_SUPPRESS_CERT_REQS) == 0);
writer.setValue("connection.strict_revocation", (mCurrentProfile.getFlags() & VpnProfile.FLAGS_STRICT_REVOCATION) != 0);
writer.setValue("connection.ike_proposal", mCurrentProfile.getIkeProposal());
writer.setValue("connection.esp_proposal", mCurrentProfile.getEspProposal());
initiate(writer.serialize());

With this

initiate(mCurrentProfile.getVpnType().getIdentifier(),
mCurrentProfile.getGateway(), mCurrentProfile.getUsername(),
mCurrentProfile.getPassword());

Now it should work.

Add Strongswan as a Module in Android app:

If u want to use strongswan in your app, add android folder from this path strongswan\src\frontends\android in your app as a module and use this project in your app.

1. Got to File->New->import module

2. Select android folder from the strongswan project directory
It will give error that the app module is already exist so change the module name from “app” to “strongswan” you can write what u want. And click finish.

3. Right click on app and click open module settings

4. Select Dependencies tab from side menu, click on “+”and select module dependency

5. Select strongswan and click ok.

6. Now you can see strongswan module is added

Do you want us to build an App for you ?

Communication is integral to human life, so is the effective meetings to professional life. Running effective meetings is very critical for every organization. Similarly, in software companies, it is very important to keep everyone up-to-date about every stage of project; whether it’s the client or Solution Architects, Developers, QA Engineers, UI/UX Designers, Team Leads and Project Managers to productively deliver your projects.

Following are the most powerful tips to run effective meetings that will definitely set you up for success.

Always set the agenda:

Always set and email the agenda to attendees at least one day prior to the meeting. It will provide sufficient time to attendees to prepare for the meeting. If the time constraint is tight, the agenda must be clearly defined for the meeting when setting it up.

Start and end on time:

The starting and ending time of the meeting should be decided earlier at all the times and better to mention in the email about expected time leeway for the meeting. Once a meeting time is set, it should be started on time and timeline of the meeting should be esteemed by all means. In case there is a need to prolong the meeting, one should first get the approval of all the members before extending it, because there might be a chance that someone has other significant tasks to perform right after the meeting.

Take notes for yourself:

Never forget to keep your writing pads with you while attending a meeting. Taking notes on your computers might not be a good idea as it will feast a feeling that probably you are getting busy in your computers, catching up on emails or messages. The key purpose to take notes for yourself in a meeting is to record any queries or tasks that have been directed to you.

Follow up on the meeting:

Determination is a key influence skill, if you want something to really happen, you must always follow up. To ensure productivity doesn’t slow you down after you leave the meeting room, instantly float meeting notes and follow up on the commitments made or you will end up without clarity about what was agreed upon.

Conclude with an actual Action Plan:

Always save the last few minutes of your meetings to discuss the next steps to be taken. Before walking out the meeting room, clear discussion should be done that what everyone agreed upon and who is responsible for what. Otherwise all the time you spent on meeting will be go in vain.

Some other vital points to consider are:

  • No use of cellphones during meetings.
  • Always come prepared.
  • Always come on time, better to be in meeting room before 5 minutes of the actual time setup for the meeting.
  • Always be focused on topic and be clear and concise. Attendees should avoid side conversations and pay attention
  • If you don’t agree with someone, disagree but defend your right to say it without being disrespectful to others
  • Never forget the Q&A session.

If you uphold all of these habits, you will see that meetings are most effective tool to get work done.

Do you want us to build an App for you ?

This image has an empty alt attribute; its file name is banner-1-1024x535.jpg

After a long wait and anticipation, at last iOS 13 supports native Dark Mode. Users would be able to choose to allow a system wide dark appearance that will be supported in all official apps. As we will see, Apple has also made it simple for developers to add dark mode support with minimum effort.

iOS 13 dark mode support changes:

  1. Status bar style : default, darkcontent , lightcontent
  2. Activity indicator : medium, large, Depreciated (gray, white, whitelarge)
  3. UILabel, UITextField, UITextView : Use Semantic Colors or Custom Colors for light and dark mode
  4. AttributedString : requires providing foregroundColor
  5. For Embedded web content : Declare supported color schemes with color-scheme, Use prefers-color-scheme media query for custom colors and image
  6. Images : Dark mode images
  7. Images Tint Color : Dark mode tint color

Let’s make a start!

If you have already done this, then it’s great and now we will discuss what you can do more to make interface better. So let’s start on “How to implement Dark Mode”.

Step 1: Colors

At the end, actually our app is to throw colors and if we are getting colors right, then we are almost ready to launch our app in dark mode.

System Colors (Dynamic)

Before iOS 13, UI Color was offering only few simple colors like black, red, white and yellow. Now, due to iOS 13 we don’t need to use these colors because these colors are static which means they can’t adopt tint changes and remain the same as they were before.

Some colors are dynamic i.e. (systemRed) and they can adopt lighter colors in dark mode and darker colors in light mode rather than remaining same as static. In iOS 13+, it’s better to use the new system color which will respect the user’s color scheme preference:

label.textColor = UIColor.label

Compatibility:

What if, instead of if #available, there was a way to abstract the color choice down one level, so we could do something like this?

label.textColor = ColorCompatibility.label

Once we cover those, we can use their red/green/blue/alpha components to create the implementation of Color Compatibility that we want:

Enum ColorCompatibility 
{
	Static var label: UIColor 
	{
		If #available(iOS 13, *)
		{
			return .label
		}
		return UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
	}

	static var secondaryLabel: UIColor 
	{
		if #available(iOS 13, *) 
		{
			return .secondaryLabel
		}
		return UIColor(red: 0.9215686274509803, green: 0.9215686274509803, blue: 0.9607843137254902, alpha: 0.6)
	}

	// ... 34 more definitions: full code in the link at the bottom
}

We can then use Color Compatibility to set any colors we need.

Custom Colors (Dynamic): The Assets Catalog

In custom colors, chances of errors are more for you and design team. Apple team has already worked on dynamic colors for our ease. In Xcode 11, we can also define variant with color set.

If we want to design our own custom color, for that, first we have to go into Assets Catalog and open the attribute inspector, and set its appearance from None to Any, Dark as shown in the below figure.

Programmatically:

In iOS 13, a new UIColor initializer was introduced:
init(dynamicProvider: @escaping (UITraitCollection) ->UIColor)
You can customize your own color, based on the userInterfaceStyle property from UITraitCollection:

extension UIColor 
{
	static func myColorForDark() -> UIColor 
	{
		if #available(iOS 13, *)
		{
			return UIColor.init 
			{ 
				(trait) -> UIColor in
				return trait.userInterfaceStyle == .dark ? UIColor.darkGray : UIColor.orange
			}
		}
		else 
		{
			return UIColor.blue
		}
	}
}

Don’t forget to enable high contrast as well.

As you can see in the below picture, we have defined four different variants for one color. Again, I strongly suggest using System and Semantic Colors as much as possible:

Step 2: Images

SF Symbols:

Apple introduced SF Symbols at WWDC19. SF Symbols is a huge collection of glyphs (over 1500!) that are available for developers to use in their own apps.

Apple itself uses SF Symbols in each stock app like Reminders, News, Maps and others.
You can fetch any of them by using the new API UIImage(systemName:)

_ = UIImage(systemName: “star.fill”)

Like SF Symbols, template images are monochrome images that are defined in our Xcode assets catalog by selecting “render as” Template Image in the Attribute Inspector. By using them, you get several advantages. To name one, you gain dark mode for free.

let myGlyphImage = UIImage(named: "myGlyph")<br>let myGlyphImageView = UIImageView(image: myGlyphImage)<br>myGlyphImageView.tintColor = .systemBlue

Other Images:

For all other kind of images that are not template images or symbols, such as photos and more, we can follow the same steps as for custom colors: set their appearance to any, Dark in the asset catalog and drop a new variant for each appearance.

We can see in the below image how to set image for dark and light mode, we also see that how we can set simulator far dark mode:

As you can see in the above picture how images have a look in dark mode and light mode.

Dynamic Images are automatically resolved by UIImageView but if we need to resolve our UIImage independently we can do so by accessing the imageAsset property on our UIImage.

let myDarkImage = UIImage(named: “SunAndMoon”)<br>let asset = myDarkImage?.imageAsset<br>Let resolvedImage = asset?.image(with: traitCollection)

Detecting Dark Mode:

There could be some cases in which you want to detect appearance changes programmatically and change your user interface accordingly

func ViewChanges()
{
	if(traitCollection.userInterfaceStyle == .dark)
	{
		MoodShift.text = "Night Mode"
	}
	else
	{
		MoodShift.text = "Light Mode"
	}
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?)
{
	super.traitCollectionDidChange(previousTraitCollection)

	let userInterfaceStyle = traitCollection.userInterfaceStyle// Either .unspecified, .light, or .dark
	// Update your user interface based on the appearance
	print(userInterfaceStyle)
	ViewChanges()
}

Specific Screens:

To override the user interface style, just override this variable in the top view or view controller and it will propagate down to subviews:

import UIKit
class CheckViewController: UIViewController 
{
	override func viewDidLoad() 
	{
		super.viewDidLoad()

		// Always adopt a Light interface style.
		overrideUserInterfaceStyle = .light
		// Do any additional setup after loading the view.
	}
}

Step 3: Drawing Attributed Text

If we are using Attributed Text, then we must have to use .foregroundColor property. Otherwise it set to black color and uses UIColor.label for correct results. As you can see in the pictures below that what happens if we don’t use .foregroundColor property.

When drawing attributed text, if not specified, the .foregroundColor property is set to .black:
set it to a proper color instead (e.g. UIColor.label).

let textDraw = "This text is an attributed string."
let attributes: [NSAttributedString.Key: AnyObject] = [ .font: UIFont.preferredFont(forTextStyle: .title3), .foregroundColor: UIColor.label]
textDraw.draw(at: CGPoint.zero, withAttributes: attributes)

A Deeper Look:

If your app completely relies on storyboards for the UI, then congratulations!
You’re now set to fully support Dark Mode.
Not all of us are this lucky, if you’re not among these people , read on.

Behind The Scenes: Draw Time

iOS picks the right tint/image of our dynamic colors/images at draw time: but when is “draw time” exactly

As you know, our views can become invalid at some point in their lifetime:

  • Maybe the user has rotated the screen.
  • Maybe a UIView needs to add a new element in the interface, etc.

You’re always guaranteed to have iOS pick the right tint/material/image when you’re inside any of the following methods:

  • UIView
    • draw()
    • layoutSubviews()
    • traitCollectionDidChange()
    • tintColorDidChange()
  • UIViewController
    • viewWillLayoutSubviews()
    • viewDidLayoutSubviews()
    • traitCollectionDidChange()
  • UIPresentationController
    • containerViewWillLayoutSubviews()
    • containerViewDidLayoutSubviews()
    • containerViewDidLayoutSubviews()

Dark Mode In CALayers:

To use dynamic colors outside of these methods you might need to manage the UITratCollection. This is needed when working with lower level classes such as CALayer, CGColor etc.

let layer = CALayer()
// get the current traitCollection used for our view
let traitCollection = view.traitCollection
traitCollection.performAsCurrent 
{
	layer.borderColor = (UIColor.self as! CGColor)
}
// Do any additional setup after loading the view.

Roadmap to start implementing Dark Mode:

  1. Download and install Xcode 11 beta
  2. Build and Run your app with dark mode enabled
  3. Fix the obvious “mistakes” spotted
  4. Add dark variants to all your assets
  5. Make sure to set the foreground key when drawing attributed text
  6. Move all your appearance logic in the “Draw time” functions
  7. Adapt Dark Mode one screen at a time:
    • Start from the .xibs files
    • Move to storyboards
    • Move to code
    • Repeat for all screens

Do you want us to build an App for you ?

Do you want us to build an App for you ?

Do you want us to build an App for you ?

Do you want us to build an App for you ?