AR Development

AR (Augmented Reality) ushered in a new era and enhanced user experience. AR is a blend of the digital and real worlds. Users can experience components like sound, images, and motion along with GPS data to make the view more attractive and informative. Gamers experience a whole new level of gaming when they playing AR games.

Third Rock Techkno is highly experienced in AR development. We develop futuristic apps and games for our clients. Do you have a great concept for a game or an interesting app? Check out the features we have worked on and let’s explore how we can work together!

Our AR Services

  • 1. 2D / 3D content loading on AR environment.
  • 2. Location based AR development
  • 3. Floor / surface detection AR app development
  • 4. Face detection AR app development
  • 5. Update to new technology in AR app development
  • 6. iOS AR App development
  • 7. Android AR app development
  • 8. Maintenance and Update AR app development
  • 9. UI/UX update app development

Our Existing Clients

We cater to a diverse clientele spanning across various industries.

Why Choose Us As Your AR Development Company

Experienced Developers

Our highly-qualified AR development experts specialize in building customized, creative and highly-interactive web and mobile applications. Whether you are a startup or an SME, our experts will get the job done.

Trusted Delivery Methods

We employ the agile methodology to keep you in the loop. Throughout AR development and mobile development, we focus on delivering solutions that meet your business goals, timeline, and budget.

Competitive Rates

Whether it is AR development or mobile development, we offer the most competitive rates on the market. Our personalized services meet different budget needs of our clients from across the globe.

Transparent Work Approach

Our AR development company ensures complete project visibility right from the time you approach us with your needs. We use email, phone, Skype, Slack, and other mediums for regular communication with our clients.

Customer Satisfaction

Our designers, developers, quality analysts, and a project manager – all strive for customer satisfaction. We deliver AR app development services that align with our clients’ needs.

Client Testimonials

Our WORK speaks louder than our WORD. Find out how we helped clients overcome challenges and succeed.


Very good communication at all stages. Always prompt to reply. Excellent quality of work. The team at Third Rock Techkno was communicative, responsive, and accommodating as they produced high-quality work.

Jonathan Wood, Smoovr


It was a pleasure working with the TRT team. Prior to contracting this group, I had a system created that was absolutely terrible and poorly developed. I also worked with a few freelancers that couldnt cut it either. TRT was actually able to execute on our concept and have built a truly solid system for our company.

Karl Pierre, Ontime

Highlights Of AR Development

Marker Detection

The marker detection technique is used to display content on the detected marker. Ideally, the marker is a 2D image that can be detected /scanned in the Augmented reality. Marker detection works based on the pre-defined image.

Markerless / Floor Detection

Markerless or floor detection works without a marker. In this case, when we need to display Augmented reality content. That content will be displayed on the floor.

3D Object Detection

3D object detection works as the 3D marker of your object. In this case, you can track your 3D object and display Augmented Reality content.

Face Detection

Face detection is a unique way to display augmented reality. In face detection, your face will be considered as a marker so you can render some content on the face.

Recent AR Development Blogs

19 Feb 2021 | 3 Min Read
Using SwiftUI Environments Values to change Tabs programmatically.

In this post, we will explore the Environment Key and EnvironmentValues to achieve the programmatic tab switching in TabView. Lets start with the empty SwiftUI template from the Xcode and Create new SwiftUI view named AppTabView.swift. Here we define our tabs in AppTabView like below. struct AppTabView: View { enum Tab { case profile case bookmarks case settings } @State private var selectedTab: Tab = .profile var body: some View { TabView(selection: $selectedTab) { ProfileView() .tabItem { Image(systemName: "person") Text("Profile") } .tag(Tab.profile) BookmarksView() .tabItem { Image(systemName: "book") Text("Bookmarks") } .tag(Tab.bookmarks) SettingsView() .tabItem { Image(systemName: "gear") Text("Settings") } .tag(Tab.settings) } } } Here you can see we have used the .tag modifier in order to TabView to switch the current tab. > If we use @SceneStorage("selectedTab") instead of @State, then we can get some level of state-restoration behaviour. Now below is the contents of the ProfileView, BookmarksView and SettingsView. struct ProfileView: View { var body: some View { NavigationView { List { Button("Bookmarks") { print("Switch to Bookmarks Tab") } Button("Settings") { print("Switch to Settings Tab") } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Profile") .navigationBarTitleDisplayMode(.inline) } } } struct BookmarksView: View { var body: some View { NavigationView { List { NavigationLink(destination: BookmarkDetailView()) { Text("ICE") } Button("Settings") { print("Switch to Settings Tab") } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Bookmarks") .navigationBarTitleDisplayMode(.inline) } } } struct SettingsView: View { var body: some View { NavigationView { List { Button("Profile") { print("Switch to Profile View") } Button("Bookmarks") { print("Switch to Bookmarsk View") } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Settings") .navigationBarTitleDisplayMode(.inline) } } } Now we have the our basic tabs setup, now we need some way to pass the button press action to super view ( AppTabView in our case ). So we can use the EnvironmentKey and EnvironmentValues here. So let's start defining our EnviromentKey named CurrentTabKey like below. struct CurrentTabKey: EnvironmentKey { static var defaultValue: AppTabView.Tab = .bookmarks } To use above EnvironmentKey we need to extend the EnvironmentValues like below. extension EnvironmentValues { var currentTab: AppTabView.Tab { get { self[CurrentTabKey.self] } set { self[CurrentTabKey.self] = newValue } } } Now we can use this CurrentTabKey like below. ... TabView(selection: $selectedTab) { ProfileView() .tabItem { Image(systemName: "person") Text("Profile") } .tag(Tab.profile) .environment(\.currentTab, selectedTab) ... And in the ProfileView we can use the environment property wrapper like below. struct ProfileView: View { @Environment(\.currentTab) var tab var body: some View { NavigationView { List { Button("Bookmarks") { tab = .bookmarks } Button("Settings") { tab = .settings } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Profile") .navigationBarTitleDisplayMode(.inline) } } } Here we can use the environment variable in our button action. But... > Cannot assign to property: 'tab' is a get-only property To solve this, we need to recall the two way data communication in SwiftUI. For this SwiftUI has property wrapper called Binding. So we update our EnvironmentKey struct CurrentTabKey like below. struct CurrentTabKey: EnvironmentKey { static var defaultValue: Binding<AppTabView.Tab> = .constant(.bookmarks) } And EnvironmentValues like below. extension EnvironmentValues { var currentTab: Binding<AppTabView.Tab> { get { self[CurrentTabKey.self] } set { self[CurrentTabKey.self] = newValue } } } > Cannot convert value 'selectedTab' of type 'AppTabView.Tab' to expected type 'Binding<AppTabView.Tab>', use wrapper instead Insert $ Fixing the above compiler error by putting the $ in the environment modifier like below. ... ProfileView() .tabItem { Image(systemName: "person") Text("Profile") } .tag(Tab.profile) .environment(\.currentTab, $selectedTab) ... And now finaly updating our Views like below. ... Button("Bookmarks") { tab.wrappedValue = .bookmarks } Button("Settings") { tab.wrappedValue = .settings } ... And here is the BookmarkDetailView. struct BookmarkDetailView: View { @Environment(\.currentTab) var tab var body: some View { List { Button("Profile") { tab.wrappedValue = .profile } } .listStyle(InsetGroupedListStyle()) .navigationTitle("Bookmark Detail") .navigationBarTitleDisplayMode(.inline) } } And here we have it. We hope you liked it. Thanks for reading.

06 Jan 2021 | 6 Min Read
Screenshot in iPhone

Introduction A Screenshot, also known as Screen capture or Screen grab, is a digital image that shows the contents of a computer display. A common screenshot is created by the operating system or software running on the device. A screenshot or screen capture may also be created by taking a photo of the screen. How to take a Screenshot in iPhone device? A screenshot can be taken on iPhone [] by simultaneously pressing the Home button and the Lock button, however on the newer iPhones X, XR, XS and 11, it is achieved by pressing the Volume up and Lock button. The screen will flash and the picture will be stored in PNG [] format in the "Camera Roll" if the device has a camera, or in "Saved Photos" if the device does not. From the iOS 11 update a little preview will pop up in the bottom left corner, which can be swiped left to save or clicked to open up an editor where the screenshot can be cropped or doodled on before being saved or shared. The screenshot feature is available with iOS 2.0 and later. What are the Different uses of Screenshots in iOS Apps Development? Screenshots can be extremely helpful when we need to demonstrate something that would otherwise be difficult to explain in words. After all, a picture is worth a thousand words! 1. Collaborate with Others When our team mates wants our input on new app or they need us to look over a screen they're creating, instead of writing a lengthy email with edits, we can take a screenshot and send it to them with marked changes. Marking up design concepts onscreen is faster and more effective than a wordy email. Different uses of screenshots2. Demonstrate How to Perform a Function We Don’t just need to tell but also show, demonstrate exactly what we’re talking about with a screenshot. By using a screenshot which shows exactly what we mean, there’s less chance that they’ll be misunderstood. And that means less confusion, less time explaining, and more time back in our day. For example, explain to a new employee how to login. Instead of telling them, we can quickly send them a screenshot that they can reference again and again without having to repeatedly ask you. A screenshot with numbered steps is quick to make and easy to understand. 3. Show Exactly What’s Happening Whenever we report a bug, we’ve likely been asked to provide a screenshot. That’s because not everyone’s device is the same. Depending on our screen, the processor that our device have, the way something appears for us could be completely different for them. The best part about screenshots? They’re easy! As Buffer notes, screenshots are powerful yet simple to use. In fact, it only takes a second to make a screenshot. A screenshot of an error message helps avoid confusion by showing them exactly what we’re seeing. 4. Show Users How App is Look a Like Through App Screenshots When publishing an app in the Apple App Store, we need to provide app screenshots. The screenshots are shown in your App Store listing and play a huge role in driving more downloads. Many mobile users will use our app screenshots to form a first impression and decide whether or not they want to download our app. Every screenshot that we provide needs to have a purpose and ultimately boast the best features of our app. A well-designed set of iOS app screenshots are: * appealing and eye-catching * clean and easy to read * straight to the point * on-brand Apple actually gives us 10 slots for screenshots. We should use all 10 slots. Every additional screenshots is an added opportunity to advertise why people should download our app. How to Create a Screenshot of Any View Inside our iPhone App? Initially we have following screen. view with button for taking screenshotWhat we want is to snapshot the direction, transform it into an UIImage, then save the image in the photo gallery. To start responding to button taps let’s add the IBAction of the button. So we have the following initial structure inside our ViewController for button: import UIKit class ViewController: UIViewController { // MARK:- IBOutlet of take a screenshot button @IBOutlet weak var takeAScreenShotButton: UIButton! { didSet { guard let button = self.takeAScreenShotButton else { return } button.backgroundColor = .blue button.setTitle("Take a Screenshot", for: .normal) button.setTitleColor(.white, for: .normal) button.layer.cornerRadius = button.frame.height / 2 } } // MARK:- IBAction of take a screenshot button @IBAction func takeAScreenShot(_ sender: UIButton) { UIView.animate(withDuration: 0.2, animations: { self.takeAScreenShotButton.isHidden = true }) { _ in self.takeAScreenShotButton.isHidden = false } //Take a screenshot here } } Now let’s add the actual screenshot-taking logic under buttons IBAction // MARK:- IBAction of take a screenshot button @IBAction func takeAScreenShot(_ sender: UIButton) { UIView.animate(withDuration: 0.2, animations: { self.takeAScreenShotButton.isHidden = true }) { _ in self.takeAScreenShotButton.isHidden = false } takeScreenshot(of: self.view) } func takeScreenshot(of view: UIView) { UIGraphicsBeginImageContextWithOptions( CGSize( width: view.bounds.width, height: view.bounds.height ), false, 2 ) view.layer.render(in: UIGraphicsGetCurrentContext()!) let screenshot = UIGraphicsGetImageFromCurrentImageContext()! UIGraphicsEndImageContext() //MARK:- to save screenshot in photo album UIImageWriteToSavedPhotosAlbum ( screenshot, self, #selector(imageWasSaved), nil ) } //Mark:- to perform a certain action on photo write @objc func imageWasSaved ( _ image: UIImage, error: Error?, context: UnsafeMutableRawPointer ) { if let error = error { print(error.localizedDescription) return } print("Image was saved in the photo gallery") // MARK:- to open photo gallery for preview screenshot URL(string:"photos-redirect://")! ) } As we can see, inside the takeScreenshot(of:) method we perform the following: * Begin creating image context based on the size of a view parameter. * Render the layer of view into that context. * Get the actual image from the context. * End image context. * Write the resulting image to saved photos album. The UIImageWriteToSavedPhotosAlbum operation requires permission to access the photo library, so we have to add the following to the Info.plist Info.plistIf we have any errors during the process, we simply print them. Otherwise, we open the Photos app to see our brand new screenshot. As a result, we have the following workflow: workflow of taking screenshot in appAs we can see we took a screenshot of direction and saved that screenshot in albums where button is not visible. How Screenshot can Expose Sensitive Information? Here are some cases where screenshot can expose sensitive information. 1. Login information can be recorded Any app that requires a login to get access to sensitive information. We need to make sure that only the intended person can log in. If screen recording or screen capture is allowed on the login it can expose confidential information. 2. Payment Information Any retail or banking app deals with payment/transactions. From a security point of view, we need to be watchful of any information being captured from the app to protect the user's account. If we aren't careful it will lead to a major leak in from application and secured transaction details will be compromised. 3. Private Conversation People now days takes screenshot of the private conversations and passes them to others without his/her consent. It is the major case of exposing sensitive information using screenshot. Is There Any Way to Detect Screenshot is Taken or Prevent Taking Screenshot? There's no way to prevent taking screenshots entirely. We can do what Snapchat does, which is by requiring the user to be touching the screen to view whatever information we are displaying. This is because the system screenshot event interrupts touches. It's not a perfect method and we can't prevent users from taking screenshots 100% of the time. How to Detect Screenshot is Taken? We can't prevent the screenshot but we can track if anyone is taking screenshots and how prevalent the issue is within our app. If our app uses a login mechanism we can identify the user and restrict app access or provide a notice (if desired) to the user. The key is to watch for the .UIApplicationUserDidTakeScreenshot message to be posted, which will happen whenever a screenshot happens. For example, this runs a screenshotTaken() method. NotificationCenter.default.addObserver( self, selector: #selector(screenshotTaken), name: UIApplication.userDidTakeScreenshotNotification, object: nil ) And we can add our logic inside screenshotTaken() method, or we can do the following. NotificationCenter.default.addObserver( forName: UIApplication.userDidTakeScreenshotNotification, object: nil, queue: OperationQueue.main ) { notification in //MARK:- Here we will enter logic of our need print("Screenshot taken!") } And we can perform action based on our need. Conclusion Taking, saving, and sharing screenshots can be extremely helpful. Not only do they help us prove our case, they also help us archive the past. For example,  a juicy gossip article we don’t want to risk forgetting. For more information about the aforementioned UIGraphics operations, see the official Apple documentation: UIGraphicsBeginImageContextWithOptions(::_:) [] UIGraphicsGetImageFromCurrentImageContext() [] UIGraphicsEndImageContext() [] Thanks for reading!

26 Oct 2020 | 3 Min Read
Getting started with combine framework

Combine is a new framework, Apple introduced in WWDC 2019. This framework provides a declarative Swift API for processing values over time. Combine allows you to write functional reactive code by providing declarative swift apis. We can compare this framework with RxSwift and RxCocoa. It allows us to process values over a time. Examples of this kind of value are network response, user interface events and other similar types of asynchronous data. There are some basic concepts that you need to understand. * Publisher: Things that produce values * Operator: Things that do work with values * Subscriber: Things that care about values We will explain all 3 points in this blog. Publisher Publishers are the basic provider of data when it is available and required. Publisher which has not any request will not provide any data (But obvious). This protocol has 2 associated types. 1. Output: The types of value it produces 2. Failure: The types of error it could encounter Publisher can emit multiple events: * An Output values of Output type * Completion of publisher * A failure with error having Error type Timer and URLSession is an enhanced type of foundation. Operator Operators are special methods that are called on publishers and return the same or different publishers. It is used to change values like adding, removing and many other operations. You can use multiple operators to perform complex processing. Each operator returns a type that implements the publisher protocol. Below is example of some operator Map Filter RemoveDuplicates Subscriber Subscriber receives values from publisher. Publishers and operators are pointless until someone is listening to the published events. Subscriber confirms following protocols. Subscriber can receive a value of type Input or termination event with either success or Failure. A subscriber receives a stream of value, completions or failure events from a publisher Let’s combine Subscriber and Publisher. Publisher will start delivering value when you call subscribe(_:) on it, passing your subscriber. At that point, publishers send subscriptions to subscribers. Rules of subscription 1. A subscriber can only have one condition. 2. Zero or more values can be published 3. At most one completion will be called Best example of a complete publisher is URLSessionTask Publisher which will complete tasks either with data response or with error response. Whenever error will be thrown, subscribers will end even if it has multiple values to pass through.. Below image will help you to understand the flow between publisher and subscriber. In short, combine is Combine = Publishers + Subscribers + Operators Lets connect Publisher and Subscriber Combine has 2 built in subscribers: Subscribers.Sink and Subscribers.Assign. You can call them either by calling this method on a publisher. sink(receiveCompletion:receiveValue:) to handle new element or completion event in closure. Assign(to:on:) to write new element to a property 1. Create a Just publisher that sends a single value and then completes. Combine has number of build in publishers including, Just 2. Connect a Subscribers.sink subscriber. It will print below. Cancellable First of all in Rx Subscription results in a disposable, which allows you to stop the subscription, Combine does not have this. If you don’t want to receive further updates, you will just de-reference the publisher chain. So apple manages this functionality with Cancellable. Cancellable protocol has a cancel method which frees up any allocated resources. According to documentation, cancellable is protocol that indicates an activity or actions may be cancelled. Benefits of using combine framework 1. Simplified asynchronous code - No more callbacks. 2. Declarative syntax - Easy to read and maintain. 3. Multithreading- You don’t have to worry about it. 4. Built in memory management - No more bugs to carry.

Get in Touch

Is your mind buzzing with ideas?
Let us know about them!

Contact Us