Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Mastering TipKit: Basics

Tags: tipkit rule code

Sign upSign InSign upSign Infatbobman ( 东坡肘子)FollowITNEXT--ListenShareTipKit is a framework introduced by Apple at WWDC 2023 that allows you to easily display tips in your applications. It can be used to introduce new features to users, help them discover hidden options, or demonstrate faster ways to accomplish tasks, among other scenarios. Tipkit is compatible with different hardware environments and operating systems within the Apple ecosystem, including iPhone, iPad, Mac, Apple Watch, and Apple TV.Developers can not only control the timing and frequency of tip display through rules and display frequency strategies, but also obtain information about the status of tips and events associated with them through the API. Although TipKit is primarily created for displaying tips, its functionality is not limited to that.I will explore the TipKit framework in two articles. In this article, we will first learn about the usage of TipKit. In the next article, we will discuss more usage tips, considerations, implementation principles, and other extended topics of using TipKit in different scenarios.Don’t miss out on the latest updates and excellent articles about Swift, SwiftUI, Core Data, and SwiftData. Subscribe to Fatbobman’s Swift Weekly and receive weekly insights and valuable content directly to your inbox.In TipKit, defining a Tip means declaring a struct that conforms to the Tip protocol. The Tip protocol defines the title, image, information for displaying a Tip, as well as the rules for determining whether the display conditions are met.The tips shown in the image below are recommended because they have operability, guidance, and easy memorization.Here are the types of information that are not suitable for displaying as tips:To make the TipKit framework work in the application, you need to execute the configuration command of the Tip container before the first Tip appears, usually in the initial stage of the application. For example:Tips.configure is used to initialize the data container. In it, TipKit stores tips and their associated event information. It also supports adjusting the global display frequency strategy of tips through parameters (detailed below).TipKit provides two ways to display tips: inline (TipView) and pop-up window (popoverTip).Apple provides a Demo that showcases various Tip functionalities. This article utilizes some of the code provided by the Demo.Using the TipView provided by TipKit, you can add tips inline within your views. Apple recommends using this style to display tips in order to avoid covering the content that people may want to see and interact with UI elements.In the above code, we first create an InlineTip instance in the view, and then place the TipView in the desired position where the Tip should appear. Developers can set the direction of the arrow by using the arrowEdge parameter. When set to nil, the arrow will not be displayed.TipView is no different from other SwiftUI views. It participates in the layout in the same way as standard SwiftUI views and has an impact on the existing layout when displayed. In other words, developers can place it in any layout container and apply various view modifiers to it.Using the popoverTip view decorator, display the Tip in the view as a top-level view.You can adjust the placement of the Tip relative to the view it is applied to by using arrowEdge. It cannot be set to nil:In iOS, pop-up windows will be presented as modal views, and interaction with other elements can only be done after closing or hiding the tip. Additionally, developers cannot apply view modifiers to the tip view popped up through popoverTip.For the TipView and popoverTip provided by TipKit, we can adjust their display effects in the following ways:In order to improve the display effect of text and images without breaking the Text and Image types, we can use appropriate modifiers. For example:This method is effective for both TipView and popoverTip views.This method only applies to TipView.You can combine unique modifiers, standard view modifiers, and Text and Image with additional information together.Just like many other SwiftUI components, TipKit also provides the ability to customize the appearance of TipViewthrough styles.Developers can choose not to add a close button in the custom style to prevent users from disabling the prompt through that means.Additionally, developers can completely abandon TipView and popoverTip and achieve complete control over the way Tips are displayed by responding to the Tip state (which will be detailed in the next article).So far, the Tips we have created are purely informational. By adding actions, we can make Tips more interactive and enable more functionality.In the above code, we first add the actions in PasswordTip. The id is used to identify different Action sources in the callback closure.In the Tip protocol, the definition of actions is @Tips.OptionsBuilder var options: [TipOption] { get }, which is a Result builder. Therefore, it can be synthesized and returned as an array of Actions using the above method.In the view, determine the source of the Action by adding a closure after TipView, and implement the corresponding operation.popoverTip also provides a version that supports actions.In this example, the implementation of the Action’s operation is done within the view because it requires the openURLprovided by the view's environment value. If the information from the view is not needed, the corresponding operation code can be directly added in the definition of the Action.If it’s only for providing the Tip view template mentioned in the previous context, there is absolutely no need for Apple to create the TipKit framework. The power of the TipKit framework lies in the fact that developers can create separate rules for each Tip and apply those rules to determine whether the Tip should be displayed.Rules are used to determine the basis for displaying or not displaying tip based on certain states (parameters) or user events, so we first need to define the required parameters and events in the Tip struct.We can define a variable in the Tip structure using the @Parameter macro to represent the application state to be tracked.Please note that the defined state is a static property, which is shared by all instances of this structure.By expanding the macro, we can see the complete code generated by @Parameter:The type of $isLoggedIn is Tips.Parameter, which provides the ability to persist the value of ParameterRuleTip.isLoggedIn.TipKit provides a @Parameter(.transient) option for @Parameter. When enabled, TipKit will use the default value provided in the Tip definition instead of the persisted value when the application restarts. This is slightly different from the transient option in Core Data or SwiftData, as in TipKit, even when the transient option is enabled, the data will still be persisted. This is mainly to facilitate dynamic synchronization of this parameter between different applications and components that use the same TipKit data source.Now, we can use the previously defined isLoggedIn property to create rules to determine if the conditions for displaying the ParameterRuleTip are met.#Rule(Self.$isLoggedIn) indicates that this rule will observe the isLoggedIn property and pass isLoggedIn as a parameter to the closure.#Rule is also a macro, and when expanded, it can be seen that TipKit's rules are built on Predicates.In the view, we can show or hide the Tip by modifying the value of isLoggedIn.In the above code, for the sake of demonstration, we modify the value of isLoggedIn by clicking a button. Of course, we can also pass the value change through a constructor, like:Actually, developers can read or set the value of ParameterRuleTip.$isLoggedIn anywhere in the application using ParameterRuleTip.isLoggedIn, regardless of whether it is in the view. TipKit will observe the changes of this value to determine whether to display ParameterRuleTip.The state of ParameterRuleTip.isLoggedIn can only be observed in real-time by TipKit and cannot be used as a source of truth for SwiftUI views.Besides determining whether to display a Tip by observing a specific state, TipKit also provides another method of creating rules using statistical analysis.First, we need to define an event for Tip, and then determine whether to display Tip based on the quantity and frequency of that event.Just like parameters, events are also static properties. id is the identifier of the event.The meaning of the following rule is that the EventRuleTip will only be displayed after the didTriggerControlEventevent has been triggered at least three times.We can generate events anywhere in the application using TipTypeName.EventProperty.donate() . TipKit records the time of each event generation and uses it as a basis for judging and filtering.In the above demonstration, we generated the corresponding events by clicking on a button. When the number of events reaches three, and the conditions of the rule are satisfied, the EventRuleTip is displayed.TipKit also provides a synchronous version of the event generation method (sendDonation) that includes callback functions.We can judge events based on multiple dimensions:Currently, in each generated Event, TipKit only records the time of event creation and has not yet opened up for custom DonationInfo. If custom DonationInfo is made available, we will be able to add more additional information when creating events, enabling more targeted rule settings.We can define various events, such as entering a specific view, clicking a button, or the application receiving network data, and use TipKit events as a means of recording and filtering, and apply them to other scenarios (detailed in the next article).If we do not set rules for a certain tip, we can consider it to have a default rule that is always true.We can also create multiple rules within a Tip. In the Tip protocol, the definition of rules is @Tips.RuleBuilder var rules: [Self.Rule] { get }, which is also a Result Builder. The multiple rules are combined using the ANDrelationship, meaning that all rules must be satisfied for the Tip to be displayed. For example, we can merge the two rules mentioned earlier using the following approach.Only display the Tip when isLoggedIn is true and the number of didTriggerControlEvent events exceeds three.In the code above, the following code appears twice::These two lines of code have the same functionality, which is to invalidate a certain Tip and record the reason.Currently, TipKit provides three types of reasons for Tip invalidation:Please note that invalidation Tip and hiding Tip are two different concepts.We use rules to determine whether a Tip meets the display conditions. However, one prerequisite is that the Tip must not have already been invalidated. If a Tip has been invalidated, even if the display rules are met, TipKit will not display it.In the previous text, we mentioned another reason for invalidating a Tip: displayCountExceeded. By defining options in the Tip, we can control the maximum number of times it is displayed.In the above code, we use the Tips.MaxDisplayCount(1) setting to ensure that the view of this Tip (whether it's TipViewor popoverTip) can only be displayed once. Once it has been displayed, TipKit will mark this Tip as invalid.TipKit also provides another option to ignore the global display frequency strategy (see below):Maybe someone would wonder, if a rule of a tip evaluates to true, will it continue to be displayed as long as it is not invalid? Wouldn’t this cause user dissatisfaction?TipKit has already taken this into consideration, so it allows developers to set the global Tip display frequency strategy through Configuration.By setting .displayFrequency(.daily) for configure, we can make the Tip that has not invalid only display once per day when the rule is true. Other settings include: hourly, weekly, monthly, immediate (no display frequency restrictions).When the options of a certain Tip are set to Tips.IgnoresDisplayFrequency(true), it will ignore the global display frequency settings.We can use the following code to reset all saved Tip data for the current application, including events, expiration status, display counts, etc. This command is typically used when testing or making significant changes to the application.This method should be executed before try? Tips.configure().In order to facilitate testing, you can use the following API to force showing or hiding the Tip:We can also modify the location where TipKit saves data. When using App Group, multiple apps or components can share the same TipKit data source. For example, if a tip is invalidated in App A, the invalidation status will also be reflected in App B.Or save the data to a specified directory.By default, TipKit’s data is saved in the Application Support directory.In this article, we introduce the basic usage of TipKit. In the next article, we will explore more about TipKit, including the data storage mechanism of TipKit, using TipKit in UIKit, using TipKit as a statistical tool in non-tooltip domains, and advanced topics such as how to implement fully custom views (without using TipView and popoverView).If you found this article helpful or enjoyed reading it, consider making a donation to support my writing. Your contribution will help me continue creating valuable content for you.Donate via Patreon, Buy Me aCoffee or PayPal.----ITNEXTAs a developer enthusiast, I enjoy fitness, wellness, and drinking tea. My energy is mainly focused on taking care of my furry pets.fatbobman ( 东坡肘子)inBetter Programming--Jacob FerusinITNEXT--8Martin HeinzinITNEXT--7fatbobman ( 东坡肘子)inITNEXT--2Artem Kvasnetskyi--Santosh Botre--2Ramdhas M--Henri Bredt--Steven Curtis--Mazvydas KatinasinCode by Maz--5HelpStatusAboutCareersBlogPrivacyTermsText to speechTeams



This post first appeared on VedVyas Articles, please read the originial post: here

Share the post

Mastering TipKit: Basics

×

Subscribe to Vedvyas Articles

Get updates delivered right to your inbox!

Thank you for your subscription

×