Machine Learning – Alan Blog https://alan.app/blog/ Alan Blog: follow the most recent Voice AI articles Tue, 23 Jan 2024 07:30:36 +0000 en-US hourly 1 https://i0.wp.com/synqqblog.wpcomstaging.com/wp-content/uploads/2019/10/favicon-32x32.png?fit=32%2C32&ssl=1 Machine Learning – Alan Blog https://alan.app/blog/ 32 32 111528672 Fine-tuning language models for the enterprise: What you need to know https://alan.app/blog/fine-tuning-language-models-for-the-enterprise-what-you-need-to-know/ https://alan.app/blog/fine-tuning-language-models-for-the-enterprise-what-you-need-to-know/#respond Mon, 17 Apr 2023 17:54:20 +0000 https://alan.app/blog/?p=5889 The media is abuzz with news about large language models (LLM) doing things that were virtually impossible for computers before. From generating text to summarizing articles and answering questions, LLMs are enhancing existing applications and unlocking new ones. However, when it comes to enterprise applications, LLMs can’t be used as...]]>

The media is abuzz with news about large language models (LLM) doing things that were virtually impossible for computers before. From generating text to summarizing articles and answering questions, LLMs are enhancing existing applications and unlocking new ones.

However, when it comes to enterprise applications, LLMs can’t be used as is. In their plain form, LLMs are not very robust and can make errors that will degrade the user experience or possibly cause irreversible mistakes. 

To solve these problems, enterprises need to adjust the LLMs to remain constrained to their business rules and knowledge base. One way to do this is through fine-tuning language models with proprietary data. Here is what you need to know.

The hallucination problem

LLMs are trained for “next token prediction.” Basically, it means that during training, they take a chunk from an existing document (e.g., Wikipedia, news website, code repositories), and try to predict the next word. Then they compare their prediction with what actually exists in the document and adjust their internal parameters to improve their prediction. By repeating this process over a very large corpus of curated text, the LLM develops a “model” of the language and model contained in the documents. It can then produce long stretches of high-quality text.

However, LLMs don’t have working models of the real world or the context of the conversation. They are missing many of the things that humans possess, such as multi-modal perception, common sense, intuitive physics, and more. This is why they can get into all kinds of trouble, including hallucinating facts, which means they can generate text that is plausible but factually incorrect. And given that they have been trained on a very wide corpus of data, they can start making up very wild facts with high confidence. 

Hallucination can be fun and entertaining when you’re using an LLM chatbot casually or to post memes on the internet. But when used in an enterprise application, hallucination can have very adverse effects. In healthcare, finance, commerce, sales, customer service, and many other areas, there is very little room for making factual mistakes.

Scientists and researchers have made solid progress in addressing the hallucination problem. But it is not gone yet. This is why it is important that app developers take measures to make sure that the LLMs that power their AI Assistants are robust and remain true to the knowledge and rules that they set for them.

Fine-tuning large language models

One of the solutions to the hallucination problem is to fine-tune LLMs on application-specific data. The developer must curate a dataset that contains text that is relevant to their application. Then they take a pretrained model and give it a few extra rounds of training on the proprietary data. Fine-tuning improves the model’s performance by limiting its output within the constraints of the knowledge contained in the application-specific documents. This is a very effective method for use cases where the LLM is applied to a very specific application, such as enterprise settings. 

A more advanced fine-tuning technique is “reinforcement learning from human feedback” (RLHF). In RLHF, a group of human annotators provide the LLM with a prompt and let it generate several outputs. They then rank each output and repeat the process with other prompts. The prompts, outputs, and rankings are then used to train a separate “reward model” which is used to rank the LLM’s output. This reward model is then used in a reinforcement learning process to align the model with the user’s intent. RLHF is the training process used in ChatGPT.

Another approach is to use ensembles of LLMs and other types of machine learning models. In this case, several models (hence the name ensemble) process the user input and generate the output. Then the ML system uses a voting mechanism to choose the best decision (e.g., the output that has received the most votes).

While mixing and fine-tuning language models is very effective, it is not trivial. Based on the type of model or service used, developers must overcome technical barriers. For example, if the company wants to self-host its own model, it must set up servers and GPU clusters, create an entire MLOps pipeline, curate the data from across its entire knowledge base, and format it in a way that can be read by the programming tools that will be retraining the model. The high costs and shortage of machine learning and data engineering talent often make it prohibitive for companies to fine-tune and use LLMs.

API services reduce some of the complexities but still require large efforts and manual labor on the part of the app developers.

Fine-tuning language models with Alan AI Platform

Alan AI is committed to providing high-quality and easy-to-use actionable AI platform for enterprise applications. From the start, our vision has been to create AI Platform that makes it easy for app developers to deploy AI solutions to create the next-generation user experience. 

Our approach ensures that the underlying AI system has the right context and knowledge to avoid the kind of mistakes that current LLMs make. The architecture of the Alan AI Platform is designed to combine the power of LLMs with your existing knowledge base, APIs, databases, or even raw web data. 

To further improve the performance of the language model that powers the Alan AI Platform, we have added fine-tuning tools that are versatile and easy to use. Our general approach to fine-tuning models for the enterprise is to provide “grounding” and “affordance.” Grounding means making sure the model’s responses are based on real facts, not hallucinations. This is done by keeping the model limited within the boundaries of the enterprises knowledge base and training data as well as the context provided by the user. Affordance means knowing the limits of the model and making sure that it only responds to the prompts and requests that fall within its capabilities.

You can see this in the Q&A Service by Alan AI, which allows you to add an Actionable AI assistant on top of the existing content.

The Q&A service is a useful tool that can provide your website with 24/7 support for your visitors. However, it is important that the AI assistant is truthful to the content and knowledge of your business. Naturally, the solution is to fine-tune the underlying language model with the content of your website.

To simplify the fine-tuning process, we have provided a simple function called corpus, which developers can use to provide the content on which they want to fine-tune their AI model. You can provide the function with a list of plain-text strings that represent your fine-tuning dataset. To further simplify the process, we also support URL-based data. Instead of providing raw text, you can provide the function with a list of URLs that point to the pages where the relevant information is located. These could be links to documentation pages, FAQs, knowledge bases, or any other content that is relevant to your application. Alan AI automatically scrapes the content of those pages and uses them to fine-tune the model, saving you the manual labor to extract the data. This can be very convenient when you already have a large corpus of documentation and want to use it to train your model.

During inference, Alan AI uses the fine-tuned model with the other proprietary features of its Actionable AI platform, which takes into account visuals, user interactions, and other data that provide further context for the assistant.

Building robust language models will be key to success in the coming wave of Actionable AI innovation. Fine-tuning is the first step we are taking to make sure all enterprises have access to the best-in-class AI technologies for their applications.

]]>
https://alan.app/blog/fine-tuning-language-models-for-the-enterprise-what-you-need-to-know/feed/ 0 5889
Role of LLMs in the Conversational AI Landscape https://alan.app/blog/role-of-llms-in-the-conversational-ai-landscape/ https://alan.app/blog/role-of-llms-in-the-conversational-ai-landscape/#respond Mon, 17 Apr 2023 16:25:27 +0000 https://alan.app/blog/?p=5869 Conversational AI has become an increasingly popular technology in recent years. This technology uses machine learning to enable computers to communicate with humans in a natural language. One of the key components of conversational AI is language models, which are used to understand and generate natural language. Among the various...]]>

Conversational AI has become an increasingly popular technology in recent years. This technology uses machine learning to enable computers to communicate with humans in a natural language. One of the key components of conversational AI is language models, which are used to understand and generate natural language. Among the various types of language models, the large language model (LLM) has become more significant in the development of conversational AI.

In this article, we will explore the role of LLMs in conversational AI and how they are being used to improve the performance of these systems.

What are LLMs?

In recent years, large language models have gained significant traction. These models are designed to understand and generate natural language by processing large amounts of text data. LLMs are based on deep learning techniques, which involve training neural networks on large datasets to learn the statistical patterns of natural language. The goal of LLMs is to be able to generate natural language text that is indistinguishable from that produced by a human.

One of the most well-known LLMs is OpenAI’s GPT-3. This model has 175 billion parameters, making it one of the largest LLMs ever developed. GPT-3 has been used in a variety of applications, including language translation, chatbots, and text generation. The success of GPT-3 has sparked a renewed interest in LLMs, and researchers are now exploring how these models can be used to improve conversational AI.

Role of LLMs in Conversational AI

LLMs are essential for creating conversational systems that can interact with humans in a natural and intuitive way. There are several ways in which LLMs are being used to improve the performance of conversational AI systems.

1. Understanding Natural Language

One of the key challenges in developing conversational AI is understanding natural language. Humans use language in a complex and nuanced way, and it can be difficult for machines to understand the meaning behind what is being said. LLMs are being used to address this challenge by providing a way to model the statistical patterns of natural language.

In particular, LLMs can be used to train natural language understanding (NLU) models that identify the intent behind user input, enabling conversational AI systems to understand what the user is saying and respond appropriately. LLMs are particularly helpful for training NLU models because they can learn from large amounts of text data, which allows them to capture the subtle nuances of natural language.

2. Generating Natural Language

Another key challenge in developing conversational AI is natural language generation (NLG). Machines need to be able to generate responses that are not only grammatically correct but also sound natural and intuitive to the user.

LLMs can be used to train natural language generation (NLG) models that can generate responses to the user’s input. NLG models are essential for creating conversational AI systems that can engage in natural and intuitive conversations with users. LLMs are particularly useful for training NLG models because they can generate high-quality text that is indistinguishable from that produced by a human.

3. Improving Conversational Flow

To create truly natural and intuitive conversations, conversational AI systems need to be able to manage dialogue and maintain context across multiple exchanges with users.
LLMs can also be used to improve the conversational flow of – these systems. Conversational flow refers to the way in which a dialog progresses between a user and a machine. LLMs help model the statistical patterns of natural language and predict the next likely response in a conversation. This lets conversational AI systems respond more quickly and accurately to user input, leading to a more natural and intuitive conversation.

Conclusion

Integration of LLMs into conversational AI platforms like Alan AI has revolutionized the field of natural language processing, enabling machines to understand and generate human language more accurately and effectively. 

As a multimodal AI platform, Alan AI leverages a combination of natural language processing, speech recognition, and non-verbal context to provide a seamless and intuitive conversational experience for users.

By including LLMs in its technology stack, Alan AI can provide a more robust and reliable natural language understanding and generation, resulting in more engaging and personalized conversations. The use of LLMs in conversational AI represents a significant step towards creating more intelligent and responsive machines that can interact with humans more naturally and intuitively.

]]>
https://alan.app/blog/role-of-llms-in-the-conversational-ai-landscape/feed/ 0 5869
In the age of LLMs, enterprises need multimodal conversational UX https://alan.app/blog/why-now-is-the-time-to-think-about-multimodal-conversational-ux/ https://alan.app/blog/why-now-is-the-time-to-think-about-multimodal-conversational-ux/#respond Wed, 22 Feb 2023 20:15:10 +0000 https://alan.app/blog/?p=5785 In the past few months, advances in large language models (LLM) have shown what could be the next big computing paradigm. ChatGPT, the latest LLM from OpenAI, has taken the world by storm, reaching 100 million users in a record time. Developers, web designers, writers, and people of all kinds...]]>

In the past few months, advances in large language models (LLM) have shown what could be the next big computing paradigm. ChatGPT, the latest LLM from OpenAI, has taken the world by storm, reaching 100 million users in a record time.

Developers, web designers, writers, and people of all kinds of professions are using ChatGPT to generate human-readable text that previously required intense human labor. And now, Microsoft, OpenAI’s main backer, is trialing a version of its Bing search engine that is enhanced by ChatGPT, posing the first real threat to Google’s $283-billion monopoly in the online search market.

Other tech giants are not far behind. Google is taking hasty measures to release Bard, its rival to ChatGPT. Amazon and Meta are running their own experiments with LLMs. And a host of tech startups are using new business models with LLM-powered products.

We’re at a critical juncture in the history of computing, which some experts compare to the huge shifts caused by the internet and mobile. Soon, conversational interfaces will become the norm in every application, and users will become comfortable with—and in fact, expect—conversational agents in websites, mobile apps, kiosks, wearables, etc.

The limits of current AI systems

As much as conversational UX is attractive, it is not as simple as adding an LLM API on top of your application. We’ve seen this in the limited success of the first generation of voice assistants such as Siri and Alexa, which tried to build one solution for all needs.

Just like human-human conversations, the space of possible actions in conversational interfaces is unlimited, which opens room for mistakes. Application developers and product managers need to build trust with their users by making sure that they minimize room for mistakes and exert control over the responses the AI gives to users. 

We’re also seeing how uncontrolled use of conversational AI can damage the user’s experience and the developer’s reputation as LLM products are going through their growing pains. In Google’s Bard demo, the AI produced untruthful facts about the James Webb telescope. Microsoft’s ChatGPT-powered Bing has been caught making egregious mistakes. A reputable news website had to retract and correct several articles that were written by an LLM after they were found to be factually wrong. And numerous similar cases are being discussed on social media and tech blogs every day.

The limits of current LLMs can be boiled down to the following:

  • They “hallucinate” and can state wrongful facts with high confidence 
  • They become inconsistent in long conversations
  • They are hard to integrate with existing applications and only take a textual input prompt as context
  • Their knowledge is limited to their training data and updating them is slow and expensive
  • They can’t interact with external data sources
  • They don’t have analytics tools to measure and enhance user experience

Multimodal conversational UX

We believe that multimodal conversational AI is the way to overcome these limits and bring trust and control to everyday applications. As the name implies, multi-modal conversational AI brings together voice, text, and touch-type interactions with several sources of information, including knowledge bases, GUI interactions, user context, and company business rules and workflows. 

This multi-modal approach makes sure the AI system has a more complete user context and can make more precise and explainable decisions.

Users can trust the AI because they can see exactly how and why the AI decided and what data points were involved in the decision-making. For example, in a healthcare application, users can make sure the AI is making inferences based on their health data and not just on its own training corpus. In aviation maintenance and repair, technicians using multi-modal conversational AI can trace back suggestions and results to specific parts, workflows, and maintenance rules. 

Developers can control the AI and make sure the underlying LLM (or other machine learning models) remains reliable and factful by integrating the enterprise knowledge corpus and data records into the training and inference processes. The AI can be integrated into the broader business rules to make sure it remains within the boundaries of decision constraints.

Multi-modality means that the AI will surface information to the user not only through text and voice but also through other means such as visual cues.

The most advanced multimodal conversational AI platform

Alan AI was developed from the ground up with the vision of serving the enterprise sector. We have designed our platform to use LLMs as well as other necessary components to serve applications in all kinds of domains, including industrial, healthcare, transportation, and more. Today, thousands of developers are using the Alan AI Platform to create conversational user experiences ranging from customer support to smart assistants on field operations in oil & gas, aviation maintenance, etc.

Alan AI is platform agnostic and supports deep integration with your application on different operating systems. It can be incorporated into your application’s interface and tie in your business logic and workflows.

Alan AI Platform provides rich analytics tools that can help you better understand the user experience and discover new ways to improve your application and create value for your users. Along with the easy-to-integrate SDK, Alan AI Platform makes sure that you can iterate much faster than the traditional application lifecycle.

As an added advantage, the Alan AI Platform has been designed with enterprise technical and security needs in mind. You have full control of your hosting environment and generated responses to build trust with your users.

Multimodal conversational UX will break the limits of existing paradigms and is the future of mobile, web, kiosks, etc. We want to make sure developers have a robust AI platform to provide this experience to their users with accuracy, trust, and control of the UX. 

]]>
https://alan.app/blog/why-now-is-the-time-to-think-about-multimodal-conversational-ux/feed/ 0 5785
Alan AI: A better alternative to Nuance Mix https://alan.app/blog/alan-ai-a-better-alternative-to-nuance-mix/ https://alan.app/blog/alan-ai-a-better-alternative-to-nuance-mix/#respond Thu, 15 Dec 2022 16:26:55 +0000 https://alan.app/blog/?p=5713 Looking for implementing a virtual assistant and considering alternatives for Nuance Mix? Find out how your business can benefit from the capabilities of Alan AI. Choosing a conversational AI platform for your business is a big decision. With many factors in different categories to evaluate – efficiency, flexibility, ease-of-use, the...]]>

Looking for implementing a virtual assistant and considering alternatives for Nuance Mix? Find out how your business can benefit from the capabilities of Alan AI.

Choosing a conversational AI platform for your business is a big decision. With many factors in different categories to evaluate – efficiency, flexibility, ease-of-use, the pricing model – you need to keep the big picture in view.

With so many competitors out there, some companies still clearly aim only for big players like Nuance Mix. Nuance Mix is indeed a comprehensive platform to design chatbots and IVR agents – but before making a final purchasing decision, it makes sense to ensure the platform is tailored to your business, customers and specific demands. 

The list of reasons to look at conversational AI competitors may be endless:

  • Ease of customization 
  • Integration and deployment options
  • Niche-specific features or missing product capabilities  
  • More flexible and affordable pricing models and so on

User Experience

Customer experience is undoubtedly at the top of any business’s priority list. Most conversational AI platforms, including Nuance Mix, offer virtual assistants with an interface that is detached from the application’s UI. But Alan AI takes a fundamentally different approach.

By default, human interactions are multimodal: in daily life, 80% of the time, we communicate through visuals, and the rest is verbal. Alan AI empowers this kind of interaction for application users. It enables in-app assistants to deliver a more intuitive and natural multimodal user experience. Multimodal experiences blend voice and graphical interfaces, so whenever users interact with the application through the voice channel, the in-app assistant’s responses are synchronized with the visuals your app has to offer.

Designed with a focus on the application, its structure and workflows, in-app assistants are more powerful than standalone chatbots. They are nested within and created for the specific aim, so they can easily lead users through their journeys, provide shortcuts to success and answer any questions.

Language Understanding

Technology is the cornerstone of conversational AI, so let’s look at what is going on under the hood.

In the conversational AI world, there are different assistant types. First are template-driven assistants that use a rigid tree-like conversational flow to resolve users’ queries – the type of assistants offered by Nuance Mix. Although they can be a great fit for straightforward tasks and simple queries, there are a number of drawbacks to be weighted. Template-driven assistants disregard the application context, the conversational style may sound robotic and the user experience may lack personalization.

Alan AI enables contextual conversations with assistants of a different type – AI-powered ones.
The Alan AI Platform provides developers with complete flexibility in building conversational flows with JavaScript programming and machine learning. 

To gain unparalleled accuracy in the users’ speech recognition and language understanding, Alan AI leverages its patented contextual Spoken Language Understanding (SLU) technology that relies on the data model and application’s non-verbal context. Owing to use of the non-verbal context, Alan AI in-app assistants are provided with awareness of what is going on in any situation and on any screen and can make dialogs dynamic, personalized and human-like.

Deployment Experience

In the deployment experience area, Alan AI is in the lead with over 45K developer signups and a total of 8.5K GitHub stars. The very first version of an in-app assistant can be designed and launched in a few days. 

The scope of supported platforms, if compared to the Nuance conversational platform,  is remarkable. Alan AI provides support for web frameworks (React, Angular, Vue, JS, Ember and Electron), iOS apps built with Swift and Obj-C, Android apps built with Kotlin and Java, and cross-platform solutions: Flutter, Ionic, React Native and Apache Cordova.

Understanding the challenges of the in-app assistant development process, Alan AI lightens the burden of releasing the brand-new voice functionality with:

  • Conversational dialog script versioning
  • Ability to publish dialog versions to different environments
  • Integration with GitHub
  • Support for gradual in-app assistant rollout with Alan’s cohorts

Pricing

While a balance between benefit and cost is what most businesses are looking for, the price also needs to be considered. Here, Alan AI has an advantage over Nuance Mix, offering multiple pricing options, with free plans for developers and flexible schemes for the enterprise.

Discover the conversational AI platform for your business at alan.app.

]]>
https://alan.app/blog/alan-ai-a-better-alternative-to-nuance-mix/feed/ 0 5713
Voice Interface: Educational Institution Apps https://alan.app/blog/voice-interface-educational-institution-apps/ https://alan.app/blog/voice-interface-educational-institution-apps/#respond Tue, 24 May 2022 18:03:25 +0000 https://alan.app/blog/?p=5391 Intelligent voice interfaces for apps have become ubiquitous. From making calls to purchases, the use cases are explosive. Its use in educational institutions as a learning aid is yet to reach its full potential, but we are certain it is on the right track and can revolutionize the way students...]]>

Intelligent voice interfaces for apps have become ubiquitous. From making calls to purchases, the use cases are explosive. Its use in educational institutions as a learning aid is yet to reach its full potential, but we are certain it is on the right track and can revolutionize the way students are educated. Given the hybrid learning trend, remote learning intertwined with the physical classroom, the challenge is to keep the student engaged and learning, regardless of the environment they are in.

To achieve critical education outcomes, it is important to focus on both technology and 21st century skills. Voice-based learning is an aid that includes a broad range of tools and enables a blended learning model- augmenting the learner’s experience and help educators with their teaching methodologies.

Voice tech applications are getting smarter over time with advances in artificial intelligence and their application in voice technology. Instructors  can simply ask their app “How many students submitted their homework assignment?”, “Who was absent in class today?”, “What are the instructions for today’s science fair?”, “ Summarize the progress of student Andy Jacobs” etc. Voice interfaces enable applications to give the right answer, faster.

Let us look at what makes voice technology a terrific aid in classrooms:

  1. Collecting data in real-time:

Voice enabled devices are great at collecting data in real-time. Using them, teachers can record students’ engagement in class, monitor participation, attendance, etc. This is a productivity tool for teachers as they can just speak to the app instead of tedious touch and type. Moreover, built in artificial intelligence and analytics capabilities empower the instructor with data analysis and real-time insights. This empowers the instructor to quickly tackle situations that need a bias for action. 

  1. Academic tracking and feedback:

The academic progress of students can be tracked over a period of time using voice interfaces. It can be done at scale for every student in the institution. It can also remind students about what is expected of them regarding assignments, deadlines, subjects they have enrolled in, etc. The institution can also use voice interfaces to deliver personalized feedback and constant updates on what is happening in the classrooms. Timely feedback on student performance is an important mechanism for management of academic outcomes- voice tech can definitely be used to accomplish this.

  1. Communal learning:

When using voice interfaces, everyone in the classroom hears the same information uniformly without any bias. The students can maintain eye contact without looking down at the computer screen. The teachers also don’t have to break eye contact with the students, thereby helping build a closer rapport with the students.  

  1. Accessing records:

Accessing student record details quickly is often difficult, even if you use a student information system. Voice interfaces make this an easy process as they are adept at large data sets. For example, if a teacher wants targeted information about a student, all they need to do is ask the app. It will share the information as soon as the question is asked. It is not just limited to academic records as educational institutions can get their entire data that was input into the system.

  1. Personalizing learning:

Thanks to the human-like features of a voice interface, it makes learning more personal and humane for the students. Students will find it easy to follow instructions from voice interfaces because of their ability to express a wide range of emotions and voice modulations. Also, personalization means accommodating different learning styles of a student body and making some adjustments to fit their unique needs.

  1. Introducing routine learning exercises:

Institutions can use voice assistants to introduce routine learning exercises such as learning words, memorizing spellings and facts, learning common phrases from foreign languages, etc. The use of voice as an aid for this is definitely a time saver for the teacher. Such methods can also positively drive engagement of students, as the voice can be blended with music to make it more appealing.

  1. Customizing tests:

Voice technology can be customized according to the needs of the student. It can come with a bunch of ready-made templates that the teacher can choose from, on a whim. Moreover, a teacher can use different templates to match the diverse student personas in a classroom.

  1. Storytelling:

We all love stories. Voice interfaces can be used to read stories to students. It could be specific to the subjects that are being taught or for the pure joy of listening to a story. It keeps the students engaged, but it also gives an opportunity for the teachers to rest. Interactive stories with engaging plot lines as a mode of instruction can help the student perform much better in classrooms. 

  1. Controlling the environment:

Teachers can use voice interfaces to control the classroom by setting the tone with instructions. These can be repeated and also modified rapidly to inform students in the classroom on protocols for learning sessions, tests, and any special announcements.

In summary, Voice interfaces can be used to deliver an immersive learning experience and make learning more attractive to both student and instructor. They are a useful aid to the institution to deliver the right education at the right time to the right student.

The team at Alan AI will be more than happy to assist you with any questions or provide a personalized demo of our intelligent voice interface  platform. Just email us at sales@alan.app

About Alan AI:

Alan’s voice interface leverages the user context and existing UI of applications, a key to understanding responses for next-gen human voice conversations. Alan AI has patent protections for its unique contextual Spoken Language Understanding (SLU) technology to accurately recognize and understand human voice, within a given context. Alan’s SLU transcoder leverages the context to convert voice directly to meaning by using raw input from speech recognition services, imparting the accuracy required for mission-critical enterprise deployments and enabling human-like conversations, rather than robotic ones. Voice based interactions, coupled with the ability to allow users to verify the entered details without having the system to reiterate inputs, provides an unmatched end-user experience.

]]>
https://alan.app/blog/voice-interface-educational-institution-apps/feed/ 0 5391
Web 3.0: Massive Adoption of Voice User Interface https://alan.app/blog/web-3-0-massive-adoption-of-voice-user-interface/ https://alan.app/blog/web-3-0-massive-adoption-of-voice-user-interface/#respond Fri, 13 May 2022 08:28:39 +0000 https://alan.app/blog/?p=5326 The evolution of Web 3.0 is fundamentally to create a more transparent, intelligent, and open internet for creators and users to share value, bringing back control of the internet from big technology players into the palm of the users. Gavin Wood coined the term “Web 3.0” in 2014, laying out...]]>

The evolution of Web 3.0 is fundamentally to create a more transparent, intelligent, and open internet for creators and users to share value, bringing back control of the internet from big technology players into the palm of the users.

Gavin Wood coined the term “Web 3.0” in 2014, laying out his vision of the future of the internet. Web 3.0 is underpinned by blockchain technology– to decentralize data and distribute it across devices- while reducing risks of massive data leaks by eliminating a central point of failure. 

By implementing artificial intelligence (AI) coupled with blockchain technology, Web 3.0 aims to redefine the web experience with structural changes for decentralization, democratization, and transparency in all facets of the internet.

Features of Web 3.0 include: 

The Semantic Web: A web of linked data, combining semantic capabilities with NLP to bring “smartness” to the web for computers to understand information much like humans, interpreting data by identifying it, linking it to other data, and relating it to ideas. The user can leverage all kinds of available data that allow them to experience a new level of connectivity.

Customization: Web personalization refers to creating a dynamic, relevant website experience for users based on behavior, location, profile, and other attributes.Web 3.0 is all about providing users with a more personalized experience within a secure and transparent environment.

Trust: Web 3.0’s decentralization promotes more transactions and engagement between peers. Users can trust the technology(blockchain) to perform many tasks in lieu of trusting humans for services such as contracts and transfer of ownership. Trust is implicit and automatic — leading to the inevitable demise of the middleman.

Ubiquity: IoT is adding billions of devices to the Web. That means billions of smart, sensor driven devices, being used by billions of users, by billions of app instances. These devices and apps consistently talk to each other, exchanging valuable data.

Voice Interface: A voice interface is expected to be a key element of Web 3.0, driving interactions between humans to devices to apps. One of the pivotal changes underway in technology today is the shift from user-generated text inputs to voice recognition and voice-activated functions. 

Some of the technologies used in creating voice interfaces include:

Automatic Speech Recognition (ASR) technology transcribes user speech at the system’s front end. By tracking audio signals, spoken words convert to text.  

Text to speech (TTS). A voice-enabled device will translate a spoken command into text, execute the command, and prepare a text reply. A TTS engine translates the text into synthetic speech to complete the interaction loop with the user.

Natural Language Understanding (NLU) determines user intent at the back end.

Both ASR and NLU are used in tandem since they typically complement each other well for all text chat bots but not for voice interfaces. Voice has a lot of noice, accents and highly contextual on what we see at the moment and here Alan AI has developed a Global Spoken Language Understanding Model for Apps for Spoken Language Understanding (SLU)

Spoken Language Understanding (SLU) technology understands and learns the nuances of spoken language in context, to deliver superior responses to questions, commands, and requests. It is also a discovery tool that can help and guide users with human-like conversational voice through any workflow process. When taking the needed leap to classify and categorize queries, SLU systems collect better data and personalize voice experiences. Products then become smarter and channel more empathy, empowered to anticipate user needs and solve problems quickly. Exactly in tune with the intent of Web 3.0.

The Alan AI platform is a SLU-based B2B Voice AI platform for developers to deploy and manage Voice Interfaces for Enterprise Apps- deployment is a matter of days, for any application. 

Alan’s voice interface leverage the user context and existing UI of applications, a key to understanding responses for next-gen human voice conversations. 

Alan has patent protections for its unique contextual Spoken Language Understanding (SLU) technology to accurately recognize and understand human voice, within a given context. Alan’s SLU transcoder leverages the context to convert voice directly to meaning by using raw input from speech recognition services, imparting the accuracy required for mission-critical enterprise deployments and enabling human-like conversations, rather than robotic ones. Voice based interactions, coupled with the ability to allow users to verify the entered details without having the system to reiterate inputs, provides an unmatched end-user experience.

]]>
https://alan.app/blog/web-3-0-massive-adoption-of-voice-user-interface/feed/ 0 5326
Women Making History in Tech https://alan.app/blog/women-making-history-in-tech/ https://alan.app/blog/women-making-history-in-tech/#respond Tue, 08 Mar 2022 05:01:00 +0000 https://alan.app/blog/?p=4655 At Alan AI, we care about making all technology easily accessible to everyone and aim to bridge this gap using voice AI. Accessibility is a value we hold in high regard and it starts within our company. We believe building a diverse team is critical in crafting our platform and covering AI ethics blindspots.]]>

At Alan AI, we care about making all technology easily accessible to everyone and aim to bridge this gap using voice AI. Accessibility is a value we hold in high regard and it starts within our company. We believe building a diverse team is critical in crafting our platform and covering AI ethics blindspots.

Internally, we want to do our part in changing the statistic that today, women hold 25% of jobs in the tech industry while making up half of the entire workforce. Externally, we want to praise those that have been the first to break barriers and encourage future generations that anything is possible.

Here are some of the many incredible women who have or currently are shaping technology.

Ada Lovelace (1815 – 1852)

Being the world’s first computer programmer, Ada Lovelace was a key contributor to the technological revolution. In 1870, Lovelace joined Charles Babbage’s work on the Analytical Engine by translating the lecture notes of an Italian engineer. During these nine months of intense analysis, she found many errors in the notes and expanded on them, leading to what is now considered the first ever algorithms that could be used in a computing machine. 

Lovelace didn’t receive the recognition she deserved until a century later when her notes were republished in the 1950s. Following this, the U.S. Department of Defense named a programming language “Ada” in her honor.

Image: Wikipedia

Grace Hopper (1906 – 1992)

Grace Hopper was an American mathematician, teacher, U.S. Navy rear admiral and pioneer in developing computer technology. Her significant work consists of helping in the WWII efforts with the Harvard Mark I computer, inventing the first compiler to translate a programmer’s instructions into computer codes and paving the way for one of the first high-level programming languages, COBOL.

When she was awarded the National Medal of Technology in 1991, she said “If you ask me what accomplishment I’m most proud of, the answer would be all the young people I’ve trained over the years; that’s more important than writing the first compiler.” Hopper is remembered at the annual Grace Hopper Celebration, the world’s largest gathering of women technologists.

Image: Computer History Museum

Mary G. Ross (1908 – 2008)

Mary Golda Ross was the first known Native American female engineer. In 1942, she joined the Lockheed Corporation, an American aerospace company, as the first female engineer. She is one of the 40 founding members of the renowned and highly secretive Skunk Works project. Much of her research and writing remains classified, even today.

Mary G. Ross is featured on the US 2019 one dollar coin.

Image: transportationhistory.org

Evelyn Boyd Granville (1924 – )

Evelyn Boyd Granville is one of first African American women to earn a Ph.D. in mathematics. After graduating from Yale and struggling to find a job due to race discrimination, she accepted a teaching position at Fisk University in Nashville, Tennessee where she taught two African American women who would go on to earn doctorates in mathematics. In 1956, she started working at IBM’s Aviation Space and Information Systems division on various projects for NASA’s Apollo space program, studying rocket trajectories and orbit computations. 

After her years in government work, Granville returned to teaching mathematics of all levels. Today she is retired but is continuously advocating for women’s education in technology. 

Image: undark.org

Annie Easley (1933 – 2011)

Annie J. Easley was an American computer scientist, mathematician, and rocket scientist. After reading an article about twin sisters working as “human computers” at the National Advisory Committee for Aeronautics (NACA), she applied for a job the next day. In 1955, she started her 34-year career at NASA (previously known as NACA), doing computations for researchers by hand and then computer programming for important projects like the Centaur high-energy booster rocket and alternative systems to solve energy problems.

Easley also served as an Equal Employment Opportunity officer and was the founder and first President of the NASA Ski Club. 

Image: Salon.com

Radia Perlman (1951 – )

The title of “Mother of the Internet” has been rightfully given to Radia Perlman, a MIT math graduate, computer programmer and network engineer. Her invention of Spanning Tree Protocol (STP) was a major contributor to making today’s internet possible. Her most recent work has been on the TRILL protocol to correct some of the shortcomings of spanning-trees.

She has done keynotes speeches across the world and is currently employed at Dell EMC. When asked about diversity in STEM, Perlman replied, “The kind of diversity that I think really matters isn’t skin shade and body shape, but different ways of thinking.”

Image: eniac.hu

Marissa Mayer (1975 – )

Former Yahoo! CEO and early Google employee, Marissa Mayer is now a co-founder of Sunshine, focusing on artificial intelligence and consumer media.

After completing her studies at Stanford University, Mayer joined Google as the first female engineer at 24 years old. Her contributions during her time there include the design of the Google homepage, Gmail, Chrome, Google Earth, and being one of the three members to develop Google Adwords. From 2012 to 2017, she held the role of president and CEO of Yahoo!. Today, Mayer is working as the co-founder of Sunshine.

Image: Martin Klimek — ZUMA Press/Alamy

Building the future

The future of technology is at the fingertips of today’s students, but the road to their success isn’t always an easy one. Here are three women-founded organizations set up to lift developers of all backgrounds, demographic and skill levels.

Girls Who Code

Working to close the gender gap in technology, Girls Who Code “envisions a world where women are proportionally represented as technical leaders, executives, founders, VCs, board members, and software engineers.” This non-profit organization was founded in 2012 by Reshma Saujani, an American lawyer and politician, who during her run for the US Congress noticed a lack of girls in computer science classrooms while campaigning. With several bestsellers like “Girls Who Code: Learn to Code and Change the World” and Ted Talk “Teach girls, bravery not perfection” viewed by thousands and sparking a worldwide conversation, Girls Who Code has today reached 500 million people and 300,000 girls in USA, Canada, India, and the United Kingdom.

Image: Carey Wagner

Black Girls Code

“The great economic equalizer of our generation, the great revolution of this generation, is indeed technology. And by embedding these skills and abilities in our youth today, we can change the nation — one girl, one woman and one generation at a time.”

~ Kimberly Bryant, founder of Black Girls Code

After her daughter’s disappointing experience at male-dominated computer camp, Kimberly Bryant decided to build an environment that encourages girls, especially from underrepresented communities, to pursue careers in STEM. This led to the creation of Black Girls Code, a non-profit organization that provides African American youth with programming skills through community outreach programs such as workshops and after school programs. Since 2011, BGC has served over 200,000 students and has the ultimate goal of teaching 1 million girls how to code by 2040.

Image: Black Girls Code

CodeNewbie

Starting as a weekly Twitter Chat to connect people that are learning to code by fellow coder Saron Yitbarek, CodeNewbie has since grown into a supportive, international online community of people learning and supporting one another’s coding journey with weekly Twitter Chats every Wednesday at 9PM EST

Saron Yitbarek also hosts several podcasts like CodeNewbie involving stories and interviews about new developers transitioning into tech careers and joining developer communities.

Image: freecodecamp.org

Happy International Women’s Day!

Inspired by the women you see here? Get started with Alan AI and build your own AI powered voice interface today.

]]>
https://alan.app/blog/women-making-history-in-tech/feed/ 0 4655
The product manager’s guide to intelligent voice interfaces https://alan.app/blog/the-product-managers-guide-to-ai-voice-assistants/ Tue, 26 Oct 2021 09:30:25 +0000 https://alan.app/blog/?p=5004 As product manager, your job is to constantly look for ways to improve your application, delight your customers, and resolve pain points. And in this regard, voice interfaces provide a unique opportunity to secure and expand your app’s position in the market where you compete. Voice assistants are not new. Siri...]]>

As product manager, your job is to constantly look for ways to improve your application, delight your customers, and resolve pain points. And in this regard, voice interfaces provide a unique opportunity to secure and expand your app’s position in the market where you compete.

Voice assistants are not new. Siri is now ten years old. But the voice interface market is nearing a turning point, where advances in artificial intelligence and mobile computing are making them a ubiquitous part of every user’s computing experience.

By giving multimodal interfaces to applications, voice assistants bring the user experience closer to human interactions. They also provide app developers with the opportunity to provide infinite functionality, an especially important factor for small-screen mobile devices and wearables. And from a product management perspective, voice interfaces enable product teams to iterate fast and add new features at a very fast pace.

However, not all voice interfaces are made equal. The first generation of voice interfaces, which made their debut on mobile operating systems and smart speakers, are limited in the scope of benefits they can bring to applications. Absence of cross-platform support, privacy concerns, and lack of contextual awareness make it very difficult to integrate these voice platforms into applications. Otherwise put, they have been created to serve the needs of their vendors, not app developers. 

Meeting these challenges is the vision behind the Alan Platform, an intelligent voice interface that has been created from ground up with product integration in mind. The Alan Platform provides superior natural language processing capabilities thanks to deep integration with your application, which enables it to draw contextual insights from various sources, including voice, interactions with application interface, and business workflows. 

Alan Platform works across all web and mobile operating systems and is easy to integrate with your application, requiring minimal changes to the backend and frontend. Your team doesn’t need to have any experience in machine learning or technical knowledge of AI to integrate the Alan Platform and use it in your application.

The Alan Platform is also a privacy- and security-friendly voice assistant. Every Alan customer gets an independent instance of the Alan Server, where they have exclusive ownership of their data. There is no third-party access to the data, and the server instance lives in a secure cloud that complies with all major enterprise-grade data protection standards.

Finally, Alan AI has been designed for super-fast iteration and infinite functionality support. The Alan Platform comes with a rich analytics tool that enables you to have fine-grained, real-time visibility into how users interact with your voice interface and graphical elements, and how they respond to changes in your application. Alan’s voice is a great source for finding current pain-points, testing hypotheses, and drawing inspiration for new ideas to improve your application.

Please send a note to sales@alan.app to get access to the white paper on “why voice should be part of your 2022 digital roadmap” and find out what the Alan Platform can do for you and how our customers are using it to transform the user experience of their applications.

]]>
5004
Alan AI Voice Interface Competition https://alan.app/blog/alan-ai-video-competition/ https://alan.app/blog/alan-ai-video-competition/#respond Thu, 09 Sep 2021 16:42:42 +0000 https://alan.app/blog/?p=4978 We’ve created a competition that allows you to showcase the voice assistant you’ve created on the Alan Platform.

To be entered into the competition, click on the link here to register. In the meantime, here are some video we’ve created for you to check out:

Hope you enter the competition. Best of luck!

In the meantime, please check out this course we designed for you. If you send in a submission of your project, let us know and we’ll provide a free code for the course.

If you would like to learn more about Alan AI in general or have any questions, please feel free to book a meeting with one of our Customer Success team members here.

]]>
https://alan.app/blog/alan-ai-video-competition/feed/ 0 4978
Top 10 Hands-Free Apps for Android 2020 https://alan.app/blog/top-10-hands-free-apps-for-android-2020/ https://alan.app/blog/top-10-hands-free-apps-for-android-2020/#respond Mon, 27 Apr 2020 13:59:57 +0000 https://alan.app/blog/?p=3360 We’ve gathered some of the most popular and useful hands-free apps for Android to see what they can offer and why other businesses should be heading in that direction as well.]]>

Forward-looking businesses are starting to explore the possibilities of introducing voice control into their applications. Therefore, we are seeing a noticeable increase in Android apps with voice-operated software that provide a hands-free experience.

We’ve gathered some of the most popular and useful hands-free apps for Android to see what they can offer and why other businesses should be heading in that direction as well.

Top 10 Hands Free Apps 2019-2020 - 1

The term “hands-free” refers to equipment or software that requires limited or no use of hands. One of the most popular ways to access controls for hands-free apps is through voice. The main goal is to make sure all users can use features within the app – regardless of their ability to physically operate the device.

Voice is being integrated into all kinds of devices, and it’s reshaping the usual state of things. Here are a few reasons why making your application hands-free is a good idea, business-wise and in general:

  • Convenience – Hands-free apps can be used anywhere: while driving, doing chores around the house, carrying things, or when you’re simply far away from the device.
  • Accessibility – These apps can be operated by people with limited hand mobility, those who are visually impaired, and other groups in need of assistive technology.
  • Time efficiency – In many situations, making a quick call takes less time than typing a lengthy message and waiting for a response. The same principle applies to voice control; it requires no clicks, no typing, or any other time-consuming actions. 
  • Simplicity – Users don’t have to be familiar with the interface to handle it. Unlike traditional apps, you hardly need any computer literacy or technical skills.
  • Multi-use – Voice control isn’t strictly tied to one function. This kind of software is incredibly versatile in terms of potential applications.

Hands-free technology is particularly useful in countries where it’s illegal to use a handheld mobile phone when you drive. These laws have been adopted in many jurisdictions around the world, which gave developers another incentive to develop the technology.

Top 10 Hands Free Apps 2019-2020 - 2.jpg

The market of hands-free applications is an interesting space right now. Let’s look at the best offerings available in the Play Store for Android users.

1. Google Assistant

Google Assistant is considered an undisputed champion of personal assistant apps developed for Android. Although it may not work on every device, the coverage is extensive. In addition to running the app on your phone, you can also integrate with smart devices such as Philips Hue lights.

The assistant can run basic functions like making calls, sending texts, emails, setting alarms and reminders, etc. On top of that, you can look up weather reports and news updates, send web searches, and play music. The range of features is constantly getting updated and expanded.

The company states the app was originally designed for people with disabilities and conditions like Parkinson’s and multiple sclerosis. However, it should come in useful for anyone who’s multitasking or has their hands full. To activate Google Assistant, users need to say “OK Google,” and it will be all ears.

2. Amazon Alexa

Amazon Alexa has pushed the trend of endless integration with many emerging smart home devices to the forefront. Contrary to popular belief, this service runs not only on Amazon Echo but also on mobile devices. 

Alexa for Android is mostly used to control integrated devices. But the functionality also supports web searches, playing music, and even ordering deliveries. If you want to launch the hands-free app, say “Alexa” and it will be ready to hear commands whether the screen is on or off. 

The device restrictions are by far the biggest downside of Amazon Alexa. So far, there is a limited number of mobile phones supporting this system. However, in terms of its abilities and intelligence, it rightly occupies the top of the list.

3. Bixby

Bixby is a relatively new addition, but it is already among the best. It’s important to mention that it’s only compatible with Samsung devices. The company may be looking into other platforms, but at this point, it only runs on devices and appliances connected to Samsung’s proprietary hub.

The app can accomplish a variety of tasks – from sending text messages and responding to basic questions to activating other applications in the device (dialer, settings menus, camera app, contacts list, and gallery). 

One of the greatest benefits of Bixby is that it adapts to the user’s voice and manner of speaking. From the get-go, it can understand different request variations like “Show me today’s weather,” “What’s the weather like?” or “What’s the forecast for today?” and it only gets smarter with time.

4. Dragon

Powered by Nuance, which is the technology behind Siri, Dragon Mobile has been in operation for many years. Essential functionality includes dictating emails, checking traffic and weather, sharing your location, and a lot more. 

There are also many customizable features aimed at simplifying how you live, work, and spend leisure time – all while minimizing touch-based interactions. Users can add their unique and personalized Nuance Voiceprint. Then, voice biometrics will only let a designated user talk and ask questions.

You can also set your own wake-up word. Unlike other services, this one gives you options to launch it with “Hi, Dragon”, “What’s up,” or anything else you like. The company is working on adding languages other than English, as well as support for the international market. 

5. Hound

While the apps described above cover the most widely used basic functionalities, Hound takes a step further. Along with doing simple searches, it can accomplish advanced tasks such as hotel booking, a sing/hum music search, looking up stocks, or even calculating a mortgage. On a lighter side, you can play interactive games like Hangman. 

The company launched partnerships with Yelp and Uber to make features like getting restaurant information and hailing a ride more precise. Another interesting feature is that it can translate whole sentences practically in real-time. 

This speech-based app is only available for United States residents. However, the process of getting the app out of beta and ready for public consumption was pretty quick, so we may see some international development. Also, there are still occasional bugs within the app. 

6. Robin

Robin has been around for a while as one of the original “Siri alternatives”. Like its counterparts, the app supports calling, sending messages, and providing the latest information on the weather, news, and more. However, the functionality still needs some work.

Intentionally or not, a lot of features available on Robin are related to car use. For example, it offers GPS navigation, gives live traffic updates, and shows the prices for gas directly on the map. You can even specify what kind of gas you need, and it will guide towards the closest station.  

To call the app into action, you can tap on the microphone button, say “Robin,” or just wave hello twice in front of your phone (which is quite a unique innovation).

7. AIVC

AIVC stands for Artificial Intelligent Voice Control. It comes in two versions: free, which contains a number of ads, and Pro. The former option covers basic functionality, whereas the Pro one provides some appealing features like TV-Receiver control, wake up mode, and others. You can control devices that are accessible over a web interface with your own preset commands.

As far as voice commands go, the app gives you the option to define specific phrases to invoke a certain action. This is done to minimize the risk of the app not understanding what you want.

AIVC performs actions on other websites and services so you can compose emails, make Facebook posts, or move over to a navigation app.

8. DataBot

DataBot is one of the simpler Android Personal assistants. You can play around with it, ask for jokes and riddles, or do other goofy stuff, but it can actually be pretty useful for various tasks. You can ask the bot to make searches online, schedule events, and make calls by just using your voice.  

It is a cross-platform application so you can sync it across all your devices: smartphones, tablets, and laptops. That way, you get a coherent, all-around hands-free experience. Also, DataBot gains experience while you’re using it. 

A slight inconvenience that DataBot has is that it comes with ads and in-app purchases. If you aren’t bothered by that, it should be a good addition to your daily routine.

9. Car Dashdroid

Car Dashdroid includes everything you could possibly need while driving – navigation, music, contacts, messages, voice commands, and more. It is also integrated with popular messaging apps like WhatsApp, Telegram, and Facebook Messenger.

What makes this app stand out as a specifically car-oriented solution is that it comes with a compass, speedometer, and plenty of other features. 

There are also customization blocks that help you arrange all tasks based on their priority. For example, if you mostly use the app for navigation, you can put it at the top. Then, you can place music control below navigation, and the list of frequently contacted people at the bottom. 

10. Drivemode

Drivemode is a simple app meant to assist users while they’re driving. Users can select from their preferred navigation app (for example, Google Maps, Waze, and HERE Maps). You can also input favorite destinations (such as home, work, and so on), play music from multiple supported apps, and access messages in a low-distraction “driving mode” overlay with audio prompts. 

Even though it’s not entirely hands-free, there is a function that presents shortcuts that you can access through tapping or swiping. Drivemode can also be integrated with Google Assistant, so the functionality can potentially be extended way beyond driving assistance.

Top 10 Hands Free Apps 2019-2020 - 13.jpg

Integrating a Hands-Free Experience with Alan

Voice AI offers immense benefits for businesses – from completing tasks more quickly to offering better user experience with verbal communication. You can add unique voice conversations, no matter the industry you’re in. The Alan platform allows you to implement hands-free, interactive functionality in your existing application with ease. 

]]>
https://alan.app/blog/top-10-hands-free-apps-for-android-2020/feed/ 0 3360
What is a voice assistant? https://alan.app/blog/voiceassistant-2/ https://alan.app/blog/voiceassistant-2/#comments Fri, 25 Oct 2019 16:58:00 +0000 https://alan.app/blog/?p=2461 A voice assistant is a digital assistant that uses voice recognition, language processing algorithms, and voice synthesis to listen to specific voice commands and return relevant information or perform specific functions as requested by the user. Based on specific commands, sometimes called intents, spoken by the user, voice assistants can...]]>

A voice assistant is a digital assistant that uses voice recognition, language processing algorithms, and voice synthesis to listen to specific voice commands and return relevant information or perform specific functions as requested by the user.

Based on specific commands, sometimes called intents, spoken by the user, voice assistants can return relevant information by listening for specific keywords and filtering out the ambient noise.

While voice assistants can be completely software based and able to integrate into most devices, some assistants are designed specifically for single device applications, such as the Amazon Alexa Wall Clock. 

Today, voice assistants are integrated into many of the devices we use on a daily basis, such as cell phones, computers, and smart speakers. Because of their wide array of integrations, There are several voice assistants who offer a very specific feature set, while some choose to be open ended to help with almost any situation at hand.

History of voice assistants

Voice assistants have a very long history that actually goes back over 100 years, which might seem surprising as apps such as Siri have only been released within the past ten years.

The very first voice activated product was released in 1922 as Radio Rex. This toy was very simple, wherein a toy dog would stay inside a dog house until the user exclaimed its name, “Rex” at which point it would jump out of the house. This was all done by an electromagnet tuned to the frequency similar to the vowel found in the word Rex, and predated modern computers by over 20 years.

At the 1952 World’s fair, Audrey was announced by Bell Labs. The Automatic Digit Recognizer was not a small simple device however, its casing stood six feet tall just to house all the materials required to recognize ten numbers!

IBM began their long history of voice assistants in 1962 at the World’s Fair in Seattle when IBM Shoebox was announced. This device was able to recognize digits 0-9 and six simple commands such as, “plus, minus” so the device could be used as a simple calculator. Its name referred to its size, similar to the average shoebox, and contained a microphone connected to three audio filters to match the electric frequencies of what was being said and matched it with already assigned values for each digit.

Darpa then funded five years of speech recognition R&D in 1971, known as the Speech Understanding Research (SUR) Program. One of the biggest innovations to come out if this was Carnegie Mellon’s Harpy, which was capable of understanding over 1,000 words.

The next decade led to amazing progress and research in the speech recognition field, leading most voice recognition devices from understanding a few hundred words to understanding thousands, and slowly making their way into consumers homes.

Then, in 1990, Dragon Dictate was introduced to consumers homes for the shocking price of $9,000! This was the first consumer oriented speech recognition program designed for home PC’s. The user could dictate to the computer one word at a time, pausing in between each word waiting for the computer to process before they could move on. Seven years later, Dragon NaturallySpeaking was released and it brought more natural conversation, able to understand continuous speech at a maximum of 100 words per minute and a much lower price tag of $695.

In 1994, Simon by IBM was the first smart voice assistant. Simon was a PDA, and really, the first smartphone in history, considering it predates HTC’s Droid by practically 25 years!

In 2008, when Android was first released, Google had slowly started rolling out voice search for its Google mobile apps on various platforms, with a dedicated Google Voice Search Application being released in 2011. This led to more and more advanced features, eventually leading to Google now and Google Voice Assistant.

Then, this was followed by Siri in 2010. Developed by SRI International with speech recognition provided by Nuance Communications, the original app was released in 2010 on the iOS App Store and was acquired two months later by Apple. Then, with the release of the iPhone 4s, Siri was officially released as an integrated voice assistant within iOS. Since then, Siri has made its way to every Apple device available and has linked all the devices together in a  single ecosystem.  

Shortly after Siri was first developed, IBM Watson is announced publicly in 2011. Watson was named after the founder of IBM, and was originally conceived in 2006 to beat humans at a game of Jeopardy. Now, Watson is one of the most intelligent, naturally speaking computer systems available.

Amazon Alexa is then announced in 2015. It’s name being inspired by the Library of Alexandria and also the hard consonant “X” in the name, helping with more accurate voice recognition. With Alexa, the Echo line of smart devices are announced to bring smart integration to consumers homes for an inexpensive route.

Alan is finally publicly announced in 2017 to take the Enterprise Application world by storm. Being first born as “Synqq”, Alan is created by the minds behind “Qik”, the very first video messaging and conferencing mobile app. Alan is the first voice AI platform aimed at enterprise applications, so while it can be found in many consumer applications, it is designed for enterprises to be able to develop and integrate quickly and efficiently!

At the bottom of the post we’ve included a Timeline to summarize the history of voice assistants!

Technology behind Voice Assistants

Voice assistants use Artificial Intelligence and Voice recognition to accurately and efficiently deliver the result that the user is looking for. While it may seem simple to ask a computer to set a timer, the technology behind it is fascinating.

Voice Recognition

Voice recognition works by taking an analog signal from a users voice and turning it into a digital signal. After doing this, the computer takes the digital signal and attempts to match it up to words and phrases to recognize the users intent. To do this, the computer requires a database of pre-existing words and syllables in a given language to be able to closely match the digital signal with. Checking the input signal with this database is known as pattern recognition, and is the primary force behind voice recognition.

Artificial Intelligence

Artificial intelligence is using machines to simulate and replicate human intelligence.

In 1950, Alan Turing (The namesake of our company) published his paper “Computing Machinery and Intelligence” that first asked the question, can machines think? Alan Turing then went on to develop the Turing Test, a method of evaluating a computer to test its capability of thinking like a human. There were four approaches later developed that defined AI, Thinking humanly/rationally, and acting humanly/rationally. While the first two deal with reasoning, the second two deal with actual behavior. Modern AI is typically seen as a computer system designed to accomplish tasks that typically require human interaction. These systems can improve upon themselves using a process known as machine learning.

Machine Learning

Machine learning refers to the subset of Artificial Intelligence where programs are created without the use of human coders manually creating the program. Instead of writing out the complete program on their own, programmers gives the AI “patterns” to recognize and learn from and then gives the AI large amounts of data to sift through and study. So instead of having specific rules to abide by, the AI searches for patterns within this data and uses it to improve its already existing functions. One way machine learning can be helpful for Voice AI, is by feeding the algorithm hours of speech from various accents and dialects.

While traditional programs requires an input and rules to develop an output, machine learning tools are given an input and an output and use that to create the program itself. There are two approaches to machine learning, supervised learning and unsupervised learning. In supervised learning, the model is given data that is already partly labeled, this means some of the data given will be already tagged with the correct answer. This helps guide the model into categorizing the rest of the data and developing a correct algorithm. In unsupervised learning, none of the data is labeled, so it is up to the model to find the pattern correctly. One of the reasons this is very useful is because it allows the model to find patterns that the creators might have never found on their own, but the data is much more unpredictable.

Different Voice Assistant approaches

Many conversational assistants today combine both a task-oriented and knowledge-oriented workflow to carry out almost any task that a user can throw at it. A task-oriented workflow might include filling out a form, while a knowledge-oriented workflow includes answering what the capital of a state might be or specifying the technical specifications of a product.

Task-oriented approach

A task-oriented approach is using goals to tasks to achieve what the user needs. This approach often integrates itself with other apps to help complete tasks. For example, if you were to ask a voice assistant to set an alarm for 3PM, it would understand this to be a task request and communicate with your default Clock application to open and set an alarm for 3PM. It would then communicate with the app to see if anything else was necessary, such as a name for the alarm, then it would communicate this need back to you. This approach does not require an extensive online database, as it is mainly using the knowledge and already existing skills of other installed applications.

Knowledge-oriented approach

A knowledge-oriented approach is the use of analytical data to help users with their tasks. This approach focuses on using online databases and already recorded knowledge to help complete tasks. An example of this approach is anytime a user asks for an internet search, it will use the online databases available to return relevant results and recommend the highest search result. If someone is searching up a trivia question, this would use a knowledge-oriented approach as it is searching for data instead of working with other apps to complete tasks.

Benefits of Voice Assistants

Some examples of what a Voice Assistant can do include:

  • Check the weather
  • Turn on/off connected smart devices
  • Search databases

One of the main reasons of the growing popularity of Voice User Interfaces (VUI) is due to the growing complexity within mobile software without an increase in screen size, leading to a huge disadvantage by using a GUI (Graphical User Interface). As more iterations of phones come out, the screen sizes stay relatively the same, leading for very cramped interfaces and creating frustrating user experiences, which is why more and more developers are switching to Voice User Interfaces.

Efficiency and Safety

While typing has become much faster as people have gotten used to using standard keyboards, using your voice will always be quicker, much more natural, and lead to less spelling errors. This leads to a much more efficient and natural intelligent workflow.

Quick learning curve

One of the greatest benefits of voice assistants is a quick learning curve. Instead of having to learn how to use devices like mice and touch screens and get used to using specific physical devices, you can just use your natural conversation tendencies and use your voice.

Wider Device Integration

Since a screen or keyboard isn’t necessary, it’s easy to place voice integration into a much wider array of devices. In the future, smart glasses, furniture, appliances, will all come with voice assistants already integrated into the device.

Why and When to use Voice Assistants

There are many use cases for using a voice assistant in todays’ world. For example, when your hands are full and you are unable to use a touch screen or keyboard, or when you are driving Let’s say you are driving and you need to change your music, you could just ask a voice assistant, “play my driving playlist”. This leads to a safer driving experience, and helps avoid the risk of distracted driving.

User Interfaces

To further understand voice assistants, it is important to take a look at the overall user Experience and what a User Interface is and how a VUI differs from a more traditional graphical user Interface that modern apps currently use. 

Graphical User Interface (GUI)

A Graphical User Interface is what is most commonly used today. For example, the internet browser you’re using to read this article is a graphical user interface. Using graphical icons and visual indicators, the user is able to interact with machines quicker and easier than before.

A Graphical User Interface can be used in something like a chatbot, where the user communicates with the device over text, and the machine responds with natural conversation text. The big downside to this is since it is done all in text, it can seem cumbersome and inefficient, and can take longer than voice in certain situations.

Voice User Interface (VUI)

An example of a VUI is something like Siri, where there is an audio cue that the device is listening, followed by a verbal response.

Most apps today combine a sense of both Graphical and Voice User Interfaces. For example, when using a maps application, you can use voice to search for destinations and the application will show you the most relevant results, placing the most important information at the top of the screen.

Some examples of popular smart assistants today are Alan, Amazon Alexa, Siri by Apple, and Google Voice Assistant.

Popular Voice Assistants

Voice Assistant adoption by platform, from Voicebot.ai

Siri

Siri is the most popular voice assistant today. Created in 2010 by SRI Inc, and purchased in 2011 by Apple, Siri has quickly become an integral part of the Apple ecosystem in bringing all the Apple devices and applications together to use in tandem with one another.

Alexa

Created by Amazon in 2014, Alexa was named due to its similarity to the Library of Alexandria. Alexa was originally inspired by the conversational voice system found on board the U.S.S. Enterprise in Star Trek. Alexa was released alongside The Amazon Echo, a smart speaker intended for consumers to dive into the world of home automation, uses the Alexa platform to allow users to interact with the Amazon ecosystem and allow for a plethora of smart devices to be connected.

Google Assistant

Originally unveiled in 2016, Google Assistant was the spiritual successor of Google Now, with the main improvement being the addition of two-way conversations. Where Google now would return answers in the form of a search results page on Google, Google Assistant gives answers in the form of natural sentences and returns recommendations in the form of Feature cards.

Cortana

Beginning in 2009, Cortana by Microsoft has had one of the longest visions of giving people access to voice assistants in their daily lives. Microsoft began shipping Cortana with all Windows 10 and Xbox devices, leading to a huge increase in the amount of registered Cortana users. In 2018 it was reported that Cortana had over 800 Million users.

Alan

In 2017 Alan set out to take voice assistants to the next level, by enabling voice AI for all applications. Using domain specific language models and contextual understanding, Alan is focused on creating a new generation of Enterprise Voice AI applications. By using the Alan Platform, developers are able to take control of voice, and create an effective workflow that best fits their users with the help of vocal commands.

Future of Voice Assistants

As AI becomes more advanced and voice technology becomes more accepted, not only will voice controlled digital assistants become more natural, they will also become more integrated into more daily devices. Also, conversations will become much more natural, emulating human conversations, which will begin to introduce more complex task flows. More and more people are using voice assistants too, as it was estimated in early 2019 that 111.8 million people in the US will use a voice assistant at least monthly, up 9.5% from last year. 

Further Integration

In the future, devices will be more integrated with voice, and it will become easier and easier to search using voice. For example, Amazon has already released a wall clock that comes enabled with Amazon Alexa, so you can ask it to set a timer or tell you the time. While these devices aren’t full blown voice activated personal assistants, they still show a lot of promise in the coming years. Using vocal commands, we will be able to work with our devices just by talking.

Natural Conversations

Currently, as users are getting more used to using voice to communicate with their digital devices, conversations can seem very broken and awkward. But in the future, as digital processing becomes quicker and people become more accustomed to using voice assistants in their everyday devices, we will see a shift where users won’t have to pause and wait for the voice assistant to catch up, and instead we will be able to have natural conversations with our voice assistants, creating a more soothing and natural experience.

More complex task flows

As conversations with voice assistants become more natural and voice recognition and digital processing becomes quicker, it won’t be uncommon to see users begin to adopt more advanced tasks in their daily routines with voice assistants. For example, instead of asking a voice assistant how long a commute is, and then asking about different options, you might be more inclined to say, “If Uber is quicker than taking the bus to work, can you reserve an Uber ride from home to work, and how long will it take?”

How to make your own voice assistant

As the amount of voice assistants available publicly begin to grow, tools are beginning to appear to create your own to make it as easy as possible to find a voice assistant that fits your needs!

For example, if you just wanted to create a specific skill, or command for a voice assistant, it might be more efficient to look into integrating a skill into an already existing voice assistant, such as Alexa. 

Amazon has actually made it incredibly simple to add your own command to the vastly growing set of publicly available Alexa Skills. You can login to AWS with the same account you have an Echo linked to, and use the tools to create a free Alexa Skill! 

Using Alan Studio, the completely browser based Voice AI IDE, you can develop, test, and push voice integration straight from your browser.

Why Alan?

Alan is a highly customizable Voice AI platform designed to work with any pre-existing application. Built with enterprise use in mind, security and business functionality are a top priority. You can leverage visual and voice context to support any workflow and improve efficiency today, and since Alan is a completely browser based IDE, you can edit your scripts on the go whenever the need arises. Long gone are the days of creating multiple versions of scripts to run on each platform, with Alan, you can use a single script version and embed into any app, iOS, Android, or Web. You can sign up today for Alan Studio and see how you can create an AI voice assistant solution to improve your quality of life!

The Alan Voice AI Platform
Click the Alan button to learn more!

Voice Assistant Timeline

  • 1922 – First Voice activated consumer product hits store shelves as “Radio Rex”
  • 1952 – Audrey, or the Automatic Digit Recognition Machine, is announced
  • 1962 – IBM Shoebox is shown for the first time at the State Fair
  • 1971 – Darpa funds five years of speech recognition research and development
  • 1976 – Harpy is shown at Carnegie Mellon
  • 1984 – IBM releases “Tangora” the first voice activated typewriter
  • 1990 – Dragon Dictate is released
  • 1994 – Simon by IBM is the first modern voice assistant released
  • 2010 – Siri is released as an app on the iOS app store
  • 2011 – IBM Watson is released
  • 2012 – Google Now is released
  • 2014 – Amazon Alexa and Echo are released
  • 2015 – Microsoft Cortana is released
  • 2017 – Alan is developed and released with the Alan Platform
From Voicebot.ai

Resources

https://whatis.techtarget.com/definition/voice-assistant

https://www.smartsheet.com/voice-assistants-artificial-intelligence

https://www.ibm.com/ibm/history/ibm100/us/en/icons/speechreco

http://www.bbc.com/future/story/20170214-the-machines-that-learned-to-listen

https://towardsdatascience.com/build-your-first-voice-assistant-85a5a49f6cc1

This article was reposted at dev.to here:
https://dev.to/alanvoiceai/what-is-a-voice-assistant-492p

]]>
https://alan.app/blog/voiceassistant-2/feed/ 2 2461
Voice In Their Apps https://alan.app/blog/voice-in-their-apps/ https://alan.app/blog/voice-in-their-apps/#respond Thu, 18 Jul 2019 21:43:41 +0000 http://alan.app/blog/?p=2214 Voice is in its infancy stage but quickly becoming the way we interact with our devices daily. The majority of voice usage comes from the big platform’s own applications and devices: Siri, Google Assistant, and the Amazon Echo device. More and more consumers have adopted voice, now on over 1B...]]>

Voice is in its infancy stage but quickly becoming the way we interact with our devices daily. The majority of voice usage comes from the big platform’s own applications and devices: Siri, Google Assistant, and the Amazon Echo device. More and more consumers have adopted voice, now on over 1B devices and the fastest growing interface ever. Voice is coming into the mainstream, however, there are a few flaws that prevent it from becoming ubiquitous as an interface: 

  • Companies must rebuild and recreate their existing functionality and branding for voice usage, requiring heavy investment in their chosen assistant, beit Alexa, Siri, or Google.
  • User context is lost after a few commands, where thousands of skills compete for a broad set of commands from users.  
  • Many multi-step voice conversations on these devices aren’t purely voice enabled — users have to go back to using touch and type with several Siri and Google Assistant skills.
  • Privacy and Security are lacking: employees from the big platform’s listen and expose user data to gain a competitive edge in Machine Learning technology. Companies don’t own the IP of what they create.

Demonstration of how developers will monetize their voice apps is also a problem. Currently the big platforms provide rewards to app developers based on their app’s monthly user engagement, as they build the market and find a way to long term monetization.
Enterprises are creating voice apps on these platforms with limited control of the experience, data, and technical investment. Despite this, voice is an important part of the future. The difficulties posed for enterprises will be eliminated. The future of voice is coming.

]]>
https://alan.app/blog/voice-in-their-apps/feed/ 0 2214
Add Visual Voice Experiences to your SAP Mobile Applications https://alan.app/blog/add-a-visual-voice-experience-to-your-sap-mobile-applications-with-alan/ https://alan.app/blog/add-a-visual-voice-experience-to-your-sap-mobile-applications-with-alan/#respond Fri, 17 May 2019 18:05:05 +0000 http://alan.app/blog/?p=2041 Recently, we created a full visual voice experience for the SAP sample application provided through the SAP Cloud Platform SDK for iOS. We did this with the new integration from the Alan Voice AI platform. Here, we’ll go over the steps we took to create this visual voice experience. You can find the full source code of this application and the supporting Alan Visual Voice scripts here.

1. Download and Install the SAP Cloud Platform SDK for iOS

Head over to SAP’s Developer page and click on “SAP Cloud Platform SDK for iOS”. Click on the top link there to download the SAP Cloud Platform SDK for iOS. Add to your Applications folder and open the Application.

2. Create the SAP Sample Application

Now, open the SAP Cloud Platform SDK on your computer, click “Create new”, then click “Sample Application”. Then follow the steps to add your SAP account, Application details, and the name of your Xcode project. This will create an Xcode project with the Sample application.

Once this is done, open the Xcode project and take a look around. Build the project and you can see it’s an application with Suppliers, Categories, Products, and Ordering information.

Now let’s integrate with Alan.

3. Integrate the application with Alan Platform

Go to Alan Studio at https://studio.alan.app. If you don’t have an account, create one to get started.

Once you login, create a Project named “SAP”. Now, we’re just going to be integrating our SAP sample application with Alan. Later we will create the voice experience.

At the top of the screen, switch from “Development” to “Production”. Now open the “Embed  Code </>” menu, then click on the “iOS” tab and review the steps.

Then, Download the iOS SDK Framework. Once you download go back to your Xcode project.In your Xcode project, create a new group named “Alan”. Drag and drop the iOS SDK Framework into this group.

Next, go to the “Embedded Binaries” section and add the SDK Framework. Make sure that you also have the framework in your project’s “Linked Frameworks and Libraries” section as well.

Now, we need to show a message asking for microphone access. To do this, go to the file info.plist. In the “Key” column, right click and select “Add Row”. For the name of the Key, input “NSMicrophoneDescription”. The value here will be the message that your users will see when they press on the Alan button for this first time in the application. For this, use the message “Alan needs microphone access to provide the voice experience for this application” or something similar.

Go back to the group you created earlier named “Alan,” right click it, and select “New File”. Select “Swift” as the filetype and name it “WindowUI+Alan”. All of the Alan button’s functions will be stored in this file, including the size, color styles, and voice states. You can find the code for this file here:

[code language="objc" collapse="true" title="WindowUI+Alan.swift"]
//
//  UIWindow+Alan.swift
//  MyDeliveries
//
//  Created by Sergey Yuryev on 22/04/2019.
//  Copyright © 2019 SAP. All rights reserved.
//

import UIKit
import AlanSDK

public final class ObjectAssociation&amp;amp;amp;amp;amp;lt;T: Any&amp;amp;amp;amp;amp;gt; {
    
    private let policy: objc_AssociationPolicy
    
    public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
        self.policy = policy
    }
    
    public subscript(index: AnyObject) -&amp;amp;amp;amp;amp;gt; T? {
        get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
        set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
    }
    
}

extension UIWindow {
    
    private static let associationAlanButton = ObjectAssociation&amp;amp;amp;amp;amp;lt;AlanButton&amp;amp;amp;amp;amp;gt;()
    private static let associationAlanText = ObjectAssociation&amp;amp;amp;amp;amp;lt;AlanText&amp;amp;amp;amp;amp;gt;()
    
    var alanButton: AlanButton? {
        get {
            return UIWindow.associationAlanButton[self]
        }
        set {
            UIWindow.associationAlanButton[self] = newValue
        }
    }
    
    var alanText: AlanText? {
        get {
            return UIWindow.associationAlanText[self]
        }
        set {
            UIWindow.associationAlanText[self] = newValue
        }
    }
    
    func moveAlanToFront() {
        if let button = self.alanButton {
            self.bringSubviewToFront(button)
        }
        if let text = self.alanText {
            self.bringSubviewToFront(text)
        }
    }
    
    func addAlan() {
        let buttonSpace: CGFloat = 20
        let buttonWidth: CGFloat = 64
        let buttonHeight: CGFloat = 64
        let textWidth: CGFloat = self.frame.maxX - buttonWidth - buttonSpace * 3
        let textHeight: CGFloat = 64
        
        let config = AlanConfig(key: "", isButtonDraggable: false)

        self.alanButton = AlanButton(config: config)
        if let button = self.alanButton {
            let safeHeight = self.frame.maxY - self.safeAreaLayoutGuide.layoutFrame.maxY
            let realX = self.frame.maxX - buttonWidth - buttonSpace
            let realY = self.frame.maxY - safeHeight - buttonHeight - buttonSpace
            
            button.frame = CGRect(x: realX, y: realY, width: buttonWidth, height: buttonHeight)
            self.addSubview(button)
            self.bringSubviewToFront(button)
        }
        
        self.alanText = AlanText(frame: CGRect.zero)
        if let text = self.alanText {
            let safeHeight = self.frame.maxY - self.safeAreaLayoutGuide.layoutFrame.maxY
            let realX = self.frame.minX + buttonSpace
            let realY = self.frame.maxY - safeHeight - textHeight - buttonSpace
            
            text.frame = CGRect(x: realX, y: realY, width: textWidth, height: textHeight)
            self.addSubview(text)
            self.bringSubviewToFront(text)
            
            text.layer.shadowColor = UIColor.black.cgColor
            text.layer.shadowOffset = CGSize(width: 0, height: 0)
            text.layer.shadowOpacity = 0.3
            text.layer.shadowRadius = 4.0
            
            for subview in text.subviews {
                if let s = subview as? UILabel {
                    s.backgroundColor = UIColor.white
                }
            }
        }
    }
}
[/code]

The next thing to do is to open the projects “ApplicationUIManager.swift” file and add a few methods required to use the voice button in the application. Here are the sections that each method should be added to:

[code language="objc" collapse="true" title="ApplicationUIManager.swift" highlight="28,92"]
//
// AlanDeliveries
//
// Created by SAP Cloud Platform SDK for iOS Assistant application on 24/04/19
//

import SAPCommon
import SAPFiori
import SAPFioriFlows
import SAPFoundation

class SnapshotViewController: UIViewController {}

class ApplicationUIManager: ApplicationUIManaging {
    // MARK: –&amp;amp;amp;amp;amp;nbsp;Properties

    let window: UIWindow

    /// Save ViewController while splash/onboarding screens are presented
    private var _savedApplicationRootViewController: UIViewController?
    private var _onboardingSplashViewController: (UIViewController &amp;amp;amp;amp;amp;amp; InfoTextSettable)?
    private var _coveringViewController: UIViewController?

    // MARK: – Init

    public init(window: UIWindow) {
        self.window = window
        self.window.addAlan()
    }

    // MARK: - ApplicationUIManaging

    func hideApplicationScreen(completionHandler: @escaping (Error?) -&amp;amp;amp;amp;amp;gt; Void) {
        // Check whether the covering screen is already presented or not
        guard self._coveringViewController == nil else {
            completionHandler(nil)
            return
        }

        self.saveApplicationScreenIfNecessary()
        self._coveringViewController = SnapshotViewController()
        self.window.rootViewController = self._coveringViewController

        completionHandler(nil)
    }

    func showSplashScreenForOnboarding(completionHandler: @escaping (Error?) -&amp;amp;amp;amp;amp;gt; Void) {
        // splash already presented
        guard self._onboardingSplashViewController == nil else {
            completionHandler(nil)
            return
        }

        setupSplashScreen()

        completionHandler(nil)
    }

    func showSplashScreenForUnlock(completionHandler: @escaping (Error?) -&amp;amp;amp;amp;amp;gt; Void) {
        guard self._onboardingSplashViewController == nil else {
            completionHandler(nil)
            return
        }

        self.saveApplicationScreenIfNecessary()

        setupSplashScreen()

        completionHandler(nil)
    }

    func showApplicationScreen(completionHandler: @escaping (Error?) -&amp;amp;amp;amp;amp;gt; Void) {
        // Check if an application screen has already been presented
        guard self.isSplashPresented else {
            completionHandler(nil)
            return
        }

        // Restore the saved application screen or create a new one
        let appViewController: UIViewController
        if let savedViewController = self._savedApplicationRootViewController {
            appViewController = savedViewController
        } else {
            let appDelegate = (UIApplication.shared.delegate as! AppDelegate)
            let splitViewController = UIStoryboard(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "MainSplitViewController") as! UISplitViewController
            splitViewController.delegate = appDelegate
            splitViewController.modalPresentationStyle = .currentContext
            splitViewController.preferredDisplayMode = .allVisible
            appViewController = splitViewController
        }
        self.window.rootViewController = appViewController
        self.window.moveAlanToFront()
        self._onboardingSplashViewController = nil
        self._savedApplicationRootViewController = nil
        self._coveringViewController = nil

        completionHandler(nil)
    }

    func releaseRootFromMemory() {
        self._savedApplicationRootViewController = nil
    }

    // MARK: –&amp;amp;amp;amp;amp;nbsp;Helpers

    private var isSplashPresented: Bool {
        return self.window.rootViewController is FUIInfoViewController || self.window.rootViewController is SnapshotViewController
    }

    /// Helper method to capture the real application screen.
    private func saveApplicationScreenIfNecessary() {
        if self._savedApplicationRootViewController == nil, !self.isSplashPresented {
            self._savedApplicationRootViewController = self.window.rootViewController
        }
    }

    private func setupSplashScreen() {
        self._onboardingSplashViewController = FUIInfoViewController.createSplashScreenInstanceFromStoryboard()
        self.window.rootViewController = self._onboardingSplashViewController

        // Set the splash screen for the specific presenter
        let modalPresenter = OnboardingFlowProvider.modalUIViewControllerPresenter
        modalPresenter.setSplashScreen(self._onboardingSplashViewController!)
        modalPresenter.animated = true
    }
}
[/code]

For the final step of the integration, return to your project in Alan Studio, open the “Embed  Code </>” menu, “iOS” tab, and copy the “Alan SDK Key”. Make sure you copy the “Production” key for this step!

Now go back to your Xcode project’s “WindowUI+Alan.swift” file. Paste key into the quotes between the quotes in the line let config = AlanConfig(key: ””, isButtonDraggable: false)

It’s time to Build the application to see how it looks. Press the big Play button in the upper left of Xcode.

See the Alan button in the bottom right of the application. Now it’s time to create the full Visual Voice experience for the application.

4. Create the Visual Voice experience in Alan

The Visual Voice experience for this application will let users ask about products, orders, and suppliers. We’ve already created the scripts for this, which you can find here. Take these scripts and copy and paste them into your project within Alan and save. You’ll want to create a new version with this script and put it on “Production”.

Now that that’s done, we need to add handlers in the application which will control the application with voice commands. Note that the handlers for your application will be slightly different. Here are examples of our handlers:

[code language="objc" collapse="true" title="WindowUI+Alan.swift" highlight="27-36,40,41,45-61,90-113,157,160-228"]
//
//  UIWindow+Alan.swift
//  MyDeliveries
//
//  Created by Sergey Yuryev on 22/04/2019.
//  Copyright © 2019 SAP. All rights reserved.
//

import UIKit
import AlanSDK

public final class ObjectAssociation&amp;amp;amp;amp;amp;amp;amp;amp;lt;T: Any&amp;amp;amp;amp;amp;amp;amp;amp;gt; {
    
    private let policy: objc_AssociationPolicy
    
    public init(policy: objc_AssociationPolicy = .OBJC_ASSOCIATION_RETAIN_NONATOMIC) {
        self.policy = policy
    }
    
    public subscript(index: AnyObject) -&amp;amp;amp;amp;amp;amp;amp;amp;gt; T? {
        get { return objc_getAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque()) as! T? }
        set { objc_setAssociatedObject(index, Unmanaged.passUnretained(self).toOpaque(), newValue, policy) }
    }
    
}

protocol ProductViewDelegate {
    func highlightProductId(_ id: String?)
    func showProductCategory(_ category: String)
    func showProductIds(_ ids: [String])
}

protocol NavigateViewDelegate {
    func navigateCategory(_ category: String)
    func navigateBack()
}

extension UIWindow {
    
    private static let navigateDelegate = ObjectAssociation&amp;amp;amp;amp;amp;amp;amp;amp;lt;NavigateViewDelegate&amp;amp;amp;amp;amp;amp;amp;amp;gt;()
    private static let productDelegate = ObjectAssociation&amp;amp;amp;amp;amp;amp;amp;amp;lt;ProductViewDelegate&amp;amp;amp;amp;amp;amp;amp;amp;gt;()
    private static let associationAlanButton = ObjectAssociation&amp;amp;amp;amp;amp;amp;amp;amp;lt;AlanButton&amp;amp;amp;amp;amp;amp;amp;amp;gt;()
    private static let associationAlanText = ObjectAssociation&amp;amp;amp;amp;amp;amp;amp;amp;lt;AlanText&amp;amp;amp;amp;amp;amp;amp;amp;gt;()
    
    var navigateViewDelegate: NavigateViewDelegate? {
        get {
            return UIWindow.navigateDelegate[self]
        }
        set {
            UIWindow.navigateDelegate[self] = newValue
        }
    }
    
    var productViewDelegate: ProductViewDelegate? {
        get {
            return UIWindow.productDelegate[self]
        }
        set {
            UIWindow.productDelegate[self] = newValue
        }
    }
    
    var alanButton: AlanButton? {
        get {
            return UIWindow.associationAlanButton[self]
        }
        set {
            UIWindow.associationAlanButton[self] = newValue
        }
    }
    
    var alanText: AlanText? {
        get {
            return UIWindow.associationAlanText[self]
        }
        set {
            UIWindow.associationAlanText[self] = newValue
        }
    }
    
    func moveAlanToFront() {
        if let button = self.alanButton {
            self.bringSubviewToFront(button)
        }
        if let text = self.alanText {
            self.bringSubviewToFront(text)
        }
    }
    
    func setVisual(_ data: [String: Any]) {
        print("setVisual: \(data)");
        if let button = self.alanButton {
            button.setVisual(data)
        }
    }
    
    func playText(_ text: String) {
        if let button = self.alanButton {
            button.playText(text)
        }
    }
    
    func playData(_ data: [String: String]) {
        if let button = self.alanButton {
            button.playData(data)
        }
    }
    
    func call(method: String, params: [String: Any], callback:@escaping ((Error?, String?) -&amp;amp;amp;amp;amp;amp;amp;amp;gt; Void)) {
        if let button = self.alanButton {
            button.call(method, withParams: params, callback: callback)
        }
    }
    
    func addAlan() {
        let buttonSpace: CGFloat = 20
        let buttonWidth: CGFloat = 64
        let buttonHeight: CGFloat = 64
        let textWidth: CGFloat = self.frame.maxX - buttonWidth - buttonSpace * 3
        let textHeight: CGFloat = 64
        
        let config = AlanConfig(key: "", isButtonDraggable: false)

        self.alanButton = AlanButton(config: config)
        if let button = self.alanButton {
            let safeHeight = self.frame.maxY - self.safeAreaLayoutGuide.layoutFrame.maxY
            let realX = self.frame.maxX - buttonWidth - buttonSpace
            let realY = self.frame.maxY - safeHeight - buttonHeight - buttonSpace
            
            button.frame = CGRect(x: realX, y: realY, width: buttonWidth, height: buttonHeight)
            self.addSubview(button)
            self.bringSubviewToFront(button)
        }
        
        self.alanText = AlanText(frame: CGRect.zero)
        if let text = self.alanText {
            let safeHeight = self.frame.maxY - self.safeAreaLayoutGuide.layoutFrame.maxY
            let realX = self.frame.minX + buttonSpace
            let realY = self.frame.maxY - safeHeight - textHeight - buttonSpace
            
            text.frame = CGRect(x: realX, y: realY, width: textWidth, height: textHeight)
            self.addSubview(text)
            self.bringSubviewToFront(text)
            
            text.layer.shadowColor = UIColor.black.cgColor
            text.layer.shadowOffset = CGSize(width: 0, height: 0)
            text.layer.shadowOpacity = 0.3
            text.layer.shadowRadius = 4.0
            
            for subview in text.subviews {
                if let s = subview as? UILabel {
                    s.backgroundColor = UIColor.white
                }
            }
        }
        
        NotificationCenter.default.addObserver(self, selector: #selector(self.handleEvent(_:)), name:NSNotification.Name(rawValue: "kAlanSDKEventNotification"), object:nil)
    }
    
    @objc func handleEvent(_ notification: Notification) {
        guard let userInfo = notification.userInfo else {
            return
        }
        guard let event = userInfo["onEvent"] as? String else {
            return
        }
        guard event == "command" else {
            return
        }
        guard let jsonString = userInfo["jsonString"] as? String else {
            return
        }
        guard let data = jsonString.data(using: .utf8) else {
            return
        }
        guard let unwrapped = try? JSONSerialization.jsonObject(with: data, options: [])  else {
            return
        }
        guard let d = unwrapped as? [String: Any] else {
            return
        }
        guard let json = d["data"] as? [String: Any] else {
            return
        }
        guard let command = json["command"] as? String else {
            return
        }
        
        if command == "showProductCategory" {
            if let value = json["value"] as? String {
                if let d = self.productViewDelegate {
                    d.showProductCategory(value)
                }
            }
        }
        else if command == "showProductIds" {
            if let value = json["value"] as? [String] {
                if let d = self.productViewDelegate {
                    d.showProductIds(value)
                }
            }
        }
        else if command == "highlightProductId" {
            if let value = json["value"] as? String {
                if let d = self.productViewDelegate {
                    d.highlightProductId(value)
                }
            }
            else {
                if let d = self.productViewDelegate {
                    d.highlightProductId(nil)
                }
            }
        }
        else if command == "navigate" {
            if let value = json["screen"] as? String {
                if let d = self.navigateViewDelegate {
                    d.navigateCategory(value)
                }
            }
        }
        else if command == "goBack" {
            if let d = self.navigateViewDelegate {
                d.navigateBack()
            }
        }
    }
}
[/code]
[code language="objc" collapse="true" title="ProductMasterViewController.swift" highlight="13,25,29-31,36-39,115-165"]
//
// AlanDeliveries
//
// Created by SAP Cloud Platform SDK for iOS Assistant application on 24/04/19
//

import Foundation
import SAPCommon
import SAPFiori
import SAPFoundation
import SAPOData

class ProductMasterViewController: FUIFormTableViewController, SAPFioriLoadingIndicator, ProductViewDelegate {
    var espmContainer: ESPMContainer&amp;amp;amp;amp;amp;amp;lt;OnlineODataProvider&amp;amp;amp;amp;amp;amp;gt;!
    public var loadEntitiesBlock: ((_ completionHandler: @escaping ([Product]?, Error?) -&amp;amp;amp;amp;amp;amp;gt; Void) -&amp;amp;amp;amp;amp;amp;gt; Void)?
    private var entities: [Product] = [Product]()
    private var allEntities: [Product] = [Product]()
    private var entityImages = [Int: UIImage]()
    private let logger = Logger.shared(named: "ProductMasterViewControllerLogger")
    private let okTitle = NSLocalizedString("keyOkButtonTitle",
                                            value: "OK",
                                            comment: "XBUT: Title of OK button.")
    var loadingIndicator: FUILoadingIndicatorView?

    var highlightedId: String?
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        if let window = UIApplication.shared.keyWindow {
            window.productViewDelegate = nil
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        if let window = UIApplication.shared.keyWindow {
            window.setVisual(["screen": "Product"])
            window.productViewDelegate = self
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.edgesForExtendedLayout = []
        // Add refreshcontrol UI
        self.refreshControl?.addTarget(self, action: #selector(self.refresh), for: UIControl.Event.valueChanged)
        self.tableView.addSubview(self.refreshControl!)
        // Cell height settings
        self.tableView.rowHeight = UITableView.automaticDimension
        self.tableView.estimatedRowHeight = 98
        self.updateTable()
    }

    var preventNavigationLoop = false
    var entitySetName: String?

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.clearsSelectionOnViewWillAppear = self.splitViewController!.isCollapsed
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // MARK: - Table view data source

    override func tableView(_: UITableView, numberOfRowsInSection _: Int) -&amp;amp;amp;amp;amp;amp;gt; Int {
        return self.entities.count
    }

    override func tableView(_: UITableView, canEditRowAt _: IndexPath) -&amp;amp;amp;amp;amp;amp;gt; Bool {
        return true
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&amp;amp;amp;amp;amp;amp;gt; UITableViewCell {
        let product = self.entities[indexPath.row]
        let cell = CellCreationHelper.objectCellWithNonEditableContent(tableView: tableView, indexPath: indexPath, key: "ProductId", value: "\(product.productID!)")
        cell.preserveDetailImageSpacing = true
        cell.headlineText = product.name
        cell.footnoteText = product.productID
        let backgroundView = UIView()
        backgroundView.backgroundColor = UIColor.white
        
        if let image = image(for: indexPath, product: product) {
            cell.detailImage = image
            cell.detailImageView.contentMode = .scaleAspectFit
        }
        if let hid = self.highlightedId, let current = product.productID, hid == current {
            backgroundView.backgroundColor = UIColor(red: 235 / 255, green: 245 / 255, blue: 255 / 255, alpha: 1.0)
        }
        cell.backgroundView = backgroundView
        return cell
    }

    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle != .delete {
            return
        }
        let currentEntity = self.entities[indexPath.row]
        self.espmContainer.deleteEntity(currentEntity) { error in
            if let error = error {
                self.logger.error("Delete entry failed.", error: error)
                AlertHelper.displayAlert(with: NSLocalizedString("keyErrorDeletingEntryTitle", value: "Delete entry failed", comment: "XTIT: Title of deleting entry error pop up."), error: error, viewController: self)
            } else {
                self.entities.remove(at: indexPath.row)
                tableView.deleteRows(at: [indexPath], with: .fade)
            }
        }
    }

    // MARK: - Data accessing
    
    func highlightProductId(_ id: String?) {
        self.highlightedId = id
        DispatchQueue.main.async {
            self.tableView.reloadData()
            self.logger.info("Alan: Table updated successfully!")
        }
    }

    internal func showProductCategory(_ category: String) {
        if category == "All" {
            self.entityImages.removeAll()
            self.entities.removeAll()
            self.entities.append(contentsOf: self.allEntities)
        }
        else {
            let filtered = self.allEntities.filter {
                if let c = $0.category, c == category {
                    return true
                }
                return false
            }
            self.entityImages.removeAll()
            self.entities.removeAll()
            self.entities.append(contentsOf: filtered)
        }
        DispatchQueue.main.async {
            let range = NSMakeRange(0, self.tableView.numberOfSections)
            let sections = NSIndexSet(indexesIn: range)
            self.tableView.reloadSections(sections as IndexSet, with: .automatic)
            self.logger.info("Alan: Table updated successfully!")
        }
        
    }
    
    internal func showProductIds(_ ids: [String]) {
        let filtered = self.allEntities.filter {
            if let productId = $0.productID, ids.contains(productId) {
                return true
            }
            return false
        }
        self.entityImages.removeAll()
        self.entities.removeAll()
        self.entities.append(contentsOf: filtered)
        DispatchQueue.main.async {
            let range = NSMakeRange(0, self.tableView.numberOfSections)
            let sections = NSIndexSet(indexesIn: range)
            self.tableView.reloadSections(sections as IndexSet, with: .automatic)
            self.logger.info("Alan: Table updated successfully!")
        }
    }
    
    
    func requestEntities(completionHandler: @escaping (Error?) -&amp;amp;amp;amp;amp;amp;gt; Void) {
        self.loadEntitiesBlock!() { entities, error in
            if let error = error {
                completionHandler(error)
                return
            }
            
            self.entities = entities!
            self.allEntities.append(contentsOf: entities!)
            
            let encoder = JSONEncoder()
            if let encodedEntityValue = try? encoder.encode(self.entities) {
                if let json = String(data: encodedEntityValue, encoding: .utf8) {
                    print(json)
                    if let window = UIApplication.shared.keyWindow {
                        window.call(method: "script::updateProductEntities", params: ["json": json] , callback: { (error, result) in
                        })
                    }
                }
            }
            
            completionHandler(nil)
        }
    }

    // MARK: - Segues

    override func prepare(for segue: UIStoryboardSegue, sender _: Any?) {
        if segue.identifier == "showDetail" {
            // Show the selected Entity on the Detail view
            guard let indexPath = self.tableView.indexPathForSelectedRow else {
                return
            }
            self.logger.info("Showing details of the chosen element.")
            let selectedEntity = self.entities[indexPath.row]
            let detailViewController = segue.destination as! ProductDetailViewController
            detailViewController.entity = selectedEntity
            detailViewController.navigationItem.leftItemsSupplementBackButton = true
            detailViewController.navigationItem.title = self.entities[(self.tableView.indexPathForSelectedRow?.row)!].productID ?? ""
            detailViewController.allowsEditableCells = false
            detailViewController.tableUpdater = self
            detailViewController.preventNavigationLoop = self.preventNavigationLoop
            detailViewController.espmContainer = self.espmContainer
            detailViewController.entitySetName = self.entitySetName
        } else if segue.identifier == "addEntity" {
            // Show the Detail view with a new Entity, which can be filled to create on the server
            self.logger.info("Showing view to add new entity.")
            let dest = segue.destination as! UINavigationController
            let detailViewController = dest.viewControllers[0] as! ProductDetailViewController
            detailViewController.title = NSLocalizedString("keyAddEntityTitle", value: "Add Entity", comment: "XTIT: Title of add new entity screen.")
            let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: detailViewController, action: #selector(detailViewController.createEntity))
            detailViewController.navigationItem.rightBarButtonItem = doneButton
            let cancelButton = UIBarButtonItem(title: NSLocalizedString("keyCancelButtonToGoPreviousScreen", value: "Cancel", comment: "XBUT: Title of Cancel button."), style: .plain, target: detailViewController, action: #selector(detailViewController.cancel))
            detailViewController.navigationItem.leftBarButtonItem = cancelButton
            detailViewController.allowsEditableCells = true
            detailViewController.tableUpdater = self
            detailViewController.espmContainer = self.espmContainer
            detailViewController.entitySetName = self.entitySetName
        }
    }

    // MARK: - Image loading

    private func image(for indexPath: IndexPath, product: Product) -&amp;amp;amp;amp;amp;amp;gt; UIImage? {
        if let image = self.entityImages[indexPath.row] {
            return image
        } else {
            espmContainer.downloadMedia(entity: product, completionHandler: { data, error in
                if let error = error {
                    self.logger.error("Download media failed. Error: \(error)", error: error)
                    return
                }
                guard let data = data else {
                    self.logger.info("Media data is empty.")
                    return
                }
                if let image = UIImage(data: data) {
                    // store the downloaded image
                    self.entityImages[indexPath.row] = image
                    // update the cell
                    DispatchQueue.main.async {
                        self.tableView.beginUpdates()
                        if let cell = self.tableView.cellForRow(at: indexPath) as? FUIObjectTableViewCell {
                            cell.detailImage = image
                            cell.detailImageView.contentMode = .scaleAspectFit
                        }
                        self.tableView.endUpdates()
                    }
                }
            })
            return nil
        }
    }

    // MARK: - Table update

    func updateTable() {
        self.showFioriLoadingIndicator()
        DispatchQueue.global().async {
            self.loadData {
                self.hideFioriLoadingIndicator()
            }
        }
    }

    private func loadData(completionHandler: @escaping () -&amp;amp;amp;amp;amp;amp;gt; Void) {
        self.requestEntities { error in
            defer {
                completionHandler()
            }
            if let error = error {
                AlertHelper.displayAlert(with: NSLocalizedString("keyErrorLoadingData", value: "Loading data failed!", comment: "XTIT: Title of loading data error pop up."), error: error, viewController: self)
                self.logger.error("Could not update table. Error: \(error)", error: error)
                return
            }
            DispatchQueue.main.async {
                self.tableView.reloadData()
                self.logger.info("Table updated successfully!")
            }
        }
    }

    @objc func refresh() {
        DispatchQueue.global().async {
            self.loadData {
                DispatchQueue.main.async {
                    self.refreshControl?.endRefreshing()
                }
            }
        }
    }
}

extension ProductMasterViewController: EntitySetUpdaterDelegate {
    func entitySetHasChanged() {
        self.updateTable()
    }
}
[/code]
[code language="objc" collapse="true" title="CollectionsViewController.swift" highlight="20,36-91,107-110"]
//
// AlanDeliveries
//
// Created by SAP Cloud Platform SDK for iOS Assistant application on 24/04/19
//

import Foundation
import SAPFiori
import SAPFioriFlows
import SAPOData

protocol EntityUpdaterDelegate {
    func entityHasChanged(_ entity: EntityValue?)
}

protocol EntitySetUpdaterDelegate {
    func entitySetHasChanged()
}

class CollectionsViewController: FUIFormTableViewController, NavigateViewDelegate {
    private var collections = CollectionType.all

    // Variable to store the selected index path
    private var selectedIndex: IndexPath?

    private let okTitle = NSLocalizedString("keyOkButtonTitle",
                                            value: "OK",
                                            comment: "XBUT: Title of OK button.")

    var isPresentedInSplitView: Bool {
        return !(self.splitViewController?.isCollapsed ?? true)
    }

    // Navigate
    
    func navigateBack() {
        DispatchQueue.main.async {
            if let navigation1 = self.splitViewController?.viewControllers.last as? UINavigationController {
                if let navigation2 = navigation1.viewControllers.last as? UINavigationController {
                    if navigation2.viewControllers.count &amp;amp;amp;amp;amp;lt; 2 {
                        navigation1.popViewController(animated: true)
                    }
                    else {
                        if let last = navigation2.viewControllers.last {
                            last.navigationController?.popViewController(animated: true)
                        }
                    }
                }
            }
        }
    }
    
    func navigateCategory(_ category: String) {
        var indexPath = IndexPath(row: 0, section: 0)
        if( category == "Sales") {
            indexPath = IndexPath(row: 6, section: 0)
        }
        else if( category == "PurchaseOrderItems") {
            indexPath = IndexPath(row: 3, section: 0)
        }
        else if( category == "ProductText") {
            indexPath = IndexPath(row: 2, section: 0)
        }
        else if( category == "PurchaseOrderHeaders") {
            indexPath = IndexPath(row: 4, section: 0)
        }
        else if( category == "Supplier") {
            indexPath = IndexPath(row: 0, section: 0)
        }
        else if( category == "Product") {
            indexPath = IndexPath(row: 9, section: 0)
        }
        else if( category == "Stock") {
            indexPath = IndexPath(row: 5, section: 0)
        }
        else if( category == "ProductCategory") {
            indexPath = IndexPath(row: 1, section: 0)
        }
        else if( category == "SalesOrder") {
            indexPath = IndexPath(row: 8, section: 0)
        }
        else if( category == "Customer") {
            indexPath = IndexPath(row: 7, section: 0)
        }
        DispatchQueue.main.async {
            self.navigationController?.popToRootViewController(animated: true)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                self.collectionSelected(at: indexPath)
            }
        }
    }
    
    // MARK: - Lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()
        self.preferredContentSize = CGSize(width: 320, height: 480)

        self.tableView.rowHeight = UITableView.automaticDimension
        self.tableView.estimatedRowHeight = 44
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        self.makeSelection()
        
        if let window = UIApplication.shared.keyWindow {
            window.setVisual(["screen": "Main"])
            window.navigateViewDelegate = self
        }
    }

    override func viewWillTransition(to _: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animate(alongsideTransition: nil, completion: { _ in
            let isNotInSplitView = !self.isPresentedInSplitView
            self.tableView.visibleCells.forEach { cell in
                // To refresh the disclosure indicator of each cell
                cell.accessoryType = isNotInSplitView ? .disclosureIndicator : .none
            }
            self.makeSelection()
        })
    }

    // MARK: - UITableViewDelegate

    override func numberOfSections(in _: UITableView) -&amp;amp;amp;amp;amp;gt; Int {
        return 1
    }

    override func tableView(_: UITableView, numberOfRowsInSection _: Int) -&amp;amp;amp;amp;amp;gt; Int {
        return collections.count
    }

    override func tableView(_: UITableView, heightForRowAt _: IndexPath) -&amp;amp;amp;amp;amp;gt; CGFloat {
        return 44
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&amp;amp;amp;amp;amp;gt; UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: FUIObjectTableViewCell.reuseIdentifier, for: indexPath) as! FUIObjectTableViewCell
        cell.headlineLabel.text = self.collections[indexPath.row].rawValue
        cell.accessoryType = !self.isPresentedInSplitView ? .disclosureIndicator : .none
        cell.isMomentarySelection = false
        return cell
    }

    override func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.collectionSelected(at: indexPath)
    }

    // CollectionType selection helper
    private func collectionSelected(at indexPath: IndexPath) {
        // Load the EntityType specific ViewController from the specific storyboard"
        var masterViewController: UIViewController!
        guard let espmContainer = OnboardingSessionManager.shared.onboardingSession?.odataController.espmContainer else {
            AlertHelper.displayAlert(with: "OData service is not reachable, please onboard again.", error: nil, viewController: self)
            return
        }
        self.selectedIndex = indexPath

        switch self.collections[indexPath.row] {
        case .suppliers:
            let supplierStoryBoard = UIStoryboard(name: "Supplier", bundle: nil)
            let supplierMasterViewController = supplierStoryBoard.instantiateViewController(withIdentifier: "SupplierMaster") as! SupplierMasterViewController
            supplierMasterViewController.espmContainer = espmContainer
            supplierMasterViewController.entitySetName = "Suppliers"
            func fetchSuppliers(_ completionHandler: @escaping ([Supplier]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchSuppliers(matching: query, completionHandler: completionHandler)
                }
            }
            supplierMasterViewController.loadEntitiesBlock = fetchSuppliers
            supplierMasterViewController.navigationItem.title = "Supplier"
            masterViewController = supplierMasterViewController
        case .productCategories:
            let productCategoryStoryBoard = UIStoryboard(name: "ProductCategory", bundle: nil)
            let productCategoryMasterViewController = productCategoryStoryBoard.instantiateViewController(withIdentifier: "ProductCategoryMaster") as! ProductCategoryMasterViewController
            productCategoryMasterViewController.espmContainer = espmContainer
            productCategoryMasterViewController.entitySetName = "ProductCategories"
            func fetchProductCategories(_ completionHandler: @escaping ([ProductCategory]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchProductCategories(matching: query, completionHandler: completionHandler)
                }
            }
            productCategoryMasterViewController.loadEntitiesBlock = fetchProductCategories
            productCategoryMasterViewController.navigationItem.title = "ProductCategory"
            masterViewController = productCategoryMasterViewController
        case .productTexts:
            let productTextStoryBoard = UIStoryboard(name: "ProductText", bundle: nil)
            let productTextMasterViewController = productTextStoryBoard.instantiateViewController(withIdentifier: "ProductTextMaster") as! ProductTextMasterViewController
            productTextMasterViewController.espmContainer = espmContainer
            productTextMasterViewController.entitySetName = "ProductTexts"
            func fetchProductTexts(_ completionHandler: @escaping ([ProductText]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchProductTexts(matching: query, completionHandler: completionHandler)
                }
            }
            productTextMasterViewController.loadEntitiesBlock = fetchProductTexts
            productTextMasterViewController.navigationItem.title = "ProductText"
            masterViewController = productTextMasterViewController
        case .purchaseOrderItems:
            let purchaseOrderItemStoryBoard = UIStoryboard(name: "PurchaseOrderItem", bundle: nil)
            let purchaseOrderItemMasterViewController = purchaseOrderItemStoryBoard.instantiateViewController(withIdentifier: "PurchaseOrderItemMaster") as! PurchaseOrderItemMasterViewController
            purchaseOrderItemMasterViewController.espmContainer = espmContainer
            purchaseOrderItemMasterViewController.entitySetName = "PurchaseOrderItems"
            func fetchPurchaseOrderItems(_ completionHandler: @escaping ([PurchaseOrderItem]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchPurchaseOrderItems(matching: query, completionHandler: completionHandler)
                }
            }
            purchaseOrderItemMasterViewController.loadEntitiesBlock = fetchPurchaseOrderItems
            purchaseOrderItemMasterViewController.navigationItem.title = "PurchaseOrderItem"
            masterViewController = purchaseOrderItemMasterViewController
        case .purchaseOrderHeaders:
            let purchaseOrderHeaderStoryBoard = UIStoryboard(name: "PurchaseOrderHeader", bundle: nil)
            let purchaseOrderHeaderMasterViewController = purchaseOrderHeaderStoryBoard.instantiateViewController(withIdentifier: "PurchaseOrderHeaderMaster") as! PurchaseOrderHeaderMasterViewController
            purchaseOrderHeaderMasterViewController.espmContainer = espmContainer
            purchaseOrderHeaderMasterViewController.entitySetName = "PurchaseOrderHeaders"
            func fetchPurchaseOrderHeaders(_ completionHandler: @escaping ([PurchaseOrderHeader]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchPurchaseOrderHeaders(matching: query, completionHandler: completionHandler)
                }
            }
            purchaseOrderHeaderMasterViewController.loadEntitiesBlock = fetchPurchaseOrderHeaders
            purchaseOrderHeaderMasterViewController.navigationItem.title = "PurchaseOrderHeader"
            masterViewController = purchaseOrderHeaderMasterViewController
        case .stock:
            let stockStoryBoard = UIStoryboard(name: "Stock", bundle: nil)
            let stockMasterViewController = stockStoryBoard.instantiateViewController(withIdentifier: "StockMaster") as! StockMasterViewController
            stockMasterViewController.espmContainer = espmContainer
            stockMasterViewController.entitySetName = "Stock"
            func fetchStock(_ completionHandler: @escaping ([Stock]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchStock(matching: query, completionHandler: completionHandler)
                }
            }
            stockMasterViewController.loadEntitiesBlock = fetchStock
            stockMasterViewController.navigationItem.title = "Stock"
            masterViewController = stockMasterViewController
        case .salesOrderItems:
            let salesOrderItemStoryBoard = UIStoryboard(name: "SalesOrderItem", bundle: nil)
            let salesOrderItemMasterViewController = salesOrderItemStoryBoard.instantiateViewController(withIdentifier: "SalesOrderItemMaster") as! SalesOrderItemMasterViewController
            salesOrderItemMasterViewController.espmContainer = espmContainer
            salesOrderItemMasterViewController.entitySetName = "SalesOrderItems"
            func fetchSalesOrderItems(_ completionHandler: @escaping ([SalesOrderItem]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchSalesOrderItems(matching: query, completionHandler: completionHandler)
                }
            }
            salesOrderItemMasterViewController.loadEntitiesBlock = fetchSalesOrderItems
            salesOrderItemMasterViewController.navigationItem.title = "SalesOrderItem"
            masterViewController = salesOrderItemMasterViewController
        case .customers:
            let customerStoryBoard = UIStoryboard(name: "Customer", bundle: nil)
            let customerMasterViewController = customerStoryBoard.instantiateViewController(withIdentifier: "CustomerMaster") as! CustomerMasterViewController
            customerMasterViewController.espmContainer = espmContainer
            customerMasterViewController.entitySetName = "Customers"
            func fetchCustomers(_ completionHandler: @escaping ([Customer]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchCustomers(matching: query, completionHandler: completionHandler)
                }
            }
            customerMasterViewController.loadEntitiesBlock = fetchCustomers
            customerMasterViewController.navigationItem.title = "Customer"
            masterViewController = customerMasterViewController
        case .salesOrderHeaders:
            let salesOrderHeaderStoryBoard = UIStoryboard(name: "SalesOrderHeader", bundle: nil)
            let salesOrderHeaderMasterViewController = salesOrderHeaderStoryBoard.instantiateViewController(withIdentifier: "SalesOrderHeaderMaster") as! SalesOrderHeaderMasterViewController
            salesOrderHeaderMasterViewController.espmContainer = espmContainer
            salesOrderHeaderMasterViewController.entitySetName = "SalesOrderHeaders"
            func fetchSalesOrderHeaders(_ completionHandler: @escaping ([SalesOrderHeader]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchSalesOrderHeaders(matching: query, completionHandler: completionHandler)
                }
            }
            salesOrderHeaderMasterViewController.loadEntitiesBlock = fetchSalesOrderHeaders
            salesOrderHeaderMasterViewController.navigationItem.title = "SalesOrderHeader"
            masterViewController = salesOrderHeaderMasterViewController
        case .products:
            let productStoryBoard = UIStoryboard(name: "Product", bundle: nil)
            let productMasterViewController = productStoryBoard.instantiateViewController(withIdentifier: "ProductMaster") as! ProductMasterViewController
            productMasterViewController.espmContainer = espmContainer
            productMasterViewController.entitySetName = "Products"
            func fetchProducts(_ completionHandler: @escaping ([Product]?, Error?) -&amp;amp;amp;amp;amp;gt; Void) {
                // Only request the first 20 values. If you want to modify the requested entities, you can do it here.
                
                let query = DataQuery().selectAll().top(20)
                do {
                    espmContainer.fetchProducts(matching: query, completionHandler: completionHandler)
                }
            }
            productMasterViewController.loadEntitiesBlock = fetchProducts
            productMasterViewController.navigationItem.title = "Product"
            masterViewController = productMasterViewController
        case .none:
            masterViewController = UIViewController()
        }

        // Load the NavigationController and present with the EntityType specific ViewController
        let mainStoryBoard = UIStoryboard(name: "Main", bundle: nil)
        let rightNavigationController = mainStoryBoard.instantiateViewController(withIdentifier: "RightNavigationController") as! UINavigationController
        rightNavigationController.viewControllers = [masterViewController]
        self.splitViewController?.showDetailViewController(rightNavigationController, sender: nil)
    }

    // MARK: - Handle highlighting of selected cell

    private func makeSelection() {
        if let selectedIndex = selectedIndex {
            tableView.selectRow(at: selectedIndex, animated: true, scrollPosition: .none)
            tableView.scrollToRow(at: selectedIndex, at: .none, animated: true)
        } else {
            selectDefault()
        }
    }

    private func selectDefault() {
        // Automatically select first element if we have two panels (iPhone plus and iPad only)
        if self.splitViewController!.isCollapsed || OnboardingSessionManager.shared.onboardingSession?.odataController.espmContainer == nil {
            return
        }
        let indexPath = IndexPath(row: 0, section: 0)
        self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .middle)
        self.collectionSelected(at: indexPath)
    }
}

[/code]

Once you’ve added your handlers in Xcode, save and build the application.

Test a few of the voice commands:

  • Open products
  • What products do you have?
  • Show notebooks less than 1500 euros
  • What’s the price of the Notebook Basic 15?

And that concludes our integration and Visual Voice experience for this SAP sample application. This application was created as part of Alan and SAP’s partnership to voice enable the enterprise. Here’s a full video on the integration. For more details, please check out Alan’s documentation here.

Feel free to provide your feedback or just ask about support via sergey@alan.app

]]>
https://alan.app/blog/add-a-visual-voice-experience-to-your-sap-mobile-applications-with-alan/feed/ 0 2041
Taking your Voice Interface to the Office https://alan.app/blog/taking-your-voice-assistant-to-the-office/ https://alan.app/blog/taking-your-voice-assistant-to-the-office/#comments Mon, 18 Dec 2017 20:24:33 +0000 https://alan.app/blog/?p=1407 1_oP1tuzGRVZS-JRkMIHwk3A

Voice assistants have been finding their way into our daily lives. Among at home voice-enabled speaker devices, Amazon has taken a 70% market foothold and sold over 25 million units, while Google trails behind at 23.8% market share and selling 5 million units. These devices, along with their mobile counterparts Siri, Cortana, and Google Assistant, have pushed voice into the mainstream, making consumers more comfortable using them as a hands-free way of getting things done.

Still, only 46% of U.S. adults use voice assistants, with the most frequent use cases being playing music, setting alarms, and checking the weather. The remaining 54% of U.S. adults say they don’t use voice assistants simply because they are not interested. And it’s no wonder, as several of the most common use cases for voice can easily be achieved with a few taps on the phone — not to mention Siri and Google’s command and response can be easily bungled, taking more time than just tapping through to the desired app.

Each tech giant is using their own strengths to approach the advantages voice enables: Amazon’s Echo is used for shopping, Apple is launching their own Home Pod early 2018, which doubles down on music, and Google is optimizing their own Home device for search. So far, Amazon seems to be the only one to deliver on the advantages of voice, letting consumers say something as simple as “Amazon order X”, which automatically completes the order and has the items shipped.

Traditional User Interfaces are complex, and completing tasks or performing a search is time-consuming. With voice, tasks can be completed in only a few words. Today for example, if you wanted to find the recent changes to a document, you would first have to open your docs app, search for the document, open it, then click on a separate button to view the recent changes. With voice, you could simply say “Are there any recent changes to the document?” and the result will be spoken back to you.

At work, we often use business applications that require training and practice to use effectively within our organization. These products help us solve complex problems, but shouldn’t require us to jump through hoops. As Steve Jobs said, “the computer is the bicycle for the mind”. Our software at work should be intelligent to help us go faster, not slow us down. With voice, we’ll be able to go faster with less effort. This is the future of voice we’re building at Alan.

]]>
https://alan.app/blog/taking-your-voice-assistant-to-the-office/feed/ 1 1407