Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Introduction to SwiftUI for NativeScript
Valor Labs profile imageDouglas Machado
Douglas Machado forValor Labs

Posted on

     

Introduction to SwiftUI for NativeScript

Building user interfaces declaratively is something the Web community has widely adopted, and nowadays, large applications are built following these principles. For example, Google launchedJetpack Compose, and Apple announcedSwiftUI atWWDC19, receiving an immensely positive response from developers.

Here atValor Software, we are always excited about new advancements in development technologies, and we are fans of NativeScript. We collaborated withnStudio to provide an effective and enjoyable SwiftUI integration for iOS apps driven by NativeScript.

In this article, we'll demonstrate how to use SwiftUI within NativeScript to explore fun new possibilities in building amazing UIs together.

Prerequisites

  • macOS Catalina or higher
  • Xcode 11 or higher
  • iOS device/simulator running iOS 13 or higher

SwiftUI Concepts

Modern iOS development is primarily done using the Swift programming language. SwiftUI uses a declarative syntax—you state what your user interface should do.

I recommend taking the officialSwiftUI tour, to get familiar with the basic concepts.

Create a NativeScript app

We can create an app using a standard TypeScript template:

ns create swiftui--tscdswiftui
Enter fullscreen modeExit fullscreen mode

This will setup what is often called a "vanilla" flavored NativeScript app. In other words, it provides basic data binding capabilities and a rather simple setup. However, what we will cover here applies to any flavor (Angular, React, Svelte, Vue, etc.). You can explore more via StackBlitz from the following:

SwiftUI Plugin

Install theSwiftUI plugin:

npminstall @nativescript/swift-ui
Enter fullscreen modeExit fullscreen mode

Note: Your minimum iOS deployment target should be at least 13.

You can add this line toApp_Resources/iOS/build.xcconfig:

IPHONEOS_DEPLOYMENT_TARGET= 13.0;
Enter fullscreen modeExit fullscreen mode

SwiftUI Usage

A. Create your SwiftUI

CreateApp_Resources/iOS/src/SampleView.swift:

importSwiftUIstructSampleView:View{varbody:someView{VStack{Text("Hello World").padding()}}}
Enter fullscreen modeExit fullscreen mode

B. Create your SwiftUI Provider

This will prepare your SwiftUI for two-way data bindings to NativeScript.

CreateApp_Resources/iOS/src/SampleViewProvider.swift:

importSwiftUI@objcclassSampleViewProvider:UIViewController,SwiftUIProvider{// MARK: INITrequiredinit?(coderaDecoder:NSCoder){super.init(coder:aDecoder)}requiredpublicinit(){super.init(nibName:nil,bundle:nil)}publicoverridefuncviewDidLoad(){super.viewDidLoad()setupSwiftUIView(content:swiftUIView)}// MARK: PRIVATEprivatevarswiftUIView=SampleView()/// Receive data from NativeScriptfuncupdateData(data:NSDictionary){// can be empty}/// Allow sending of data to NativeScriptvaronEvent:((NSDictionary)->())?}
Enter fullscreen modeExit fullscreen mode

C. Insert into any NativeScript layout

  • app/main-page.xml
<Pagexmlns="http://schemas.nativescript.org/tns.xsd"xmlns:sw="@nativescript/swift-ui"class="page"><StackLayout><sw:SwiftUIswiftId="sampleView"height="100"/></StackLayout></Page>
Enter fullscreen modeExit fullscreen mode

D. Register your SwiftUI via the swiftId

This can be done in the NativeScript app's bootstrap file (oftenapp.ts ormain.ts).

  • app.ts
import{registerSwiftUI,UIDataDriver}from"@nativescript/swift-ui";// A. You can generate types for your own Swift Provider with 'ns typings ios'// B. Otherwise you can ignore by declaring the class name you know you provideddeclareconstSampleViewProvider:any;registerSwiftUI("sampleView",(view)=>newUIDataDriver(SampleViewProvider.alloc().init(),view));
Enter fullscreen modeExit fullscreen mode

You can now run the app withns debug ios.

Use Xcode to develop your SwiftUI

After running the project once, you can open it in Xcode to further develop your SwiftUI using all the convenient aid of Xcode intellisense.

For example from the root of your project:

open platforms/ios/swiftui.xcworkspace
Enter fullscreen modeExit fullscreen mode

You will find your.swift code underneath theTNSNativeSource folder as seen here...

Using Xcode to develop SwiftUI within context of NativeScript app

iOS Preview


Basic View App Screenshot

Advanced SwiftUI Integration

Let's dive deeper by hooking up data bindings + events between SwiftUI and NativeScript.

Create the SwiftUI component

This can be any SwiftUI you would like to use in NativeScript.

CreateApp_Resources/iOS/src/SampleView.swift:

importSwiftUIclassButtonProps:ObservableObject{@Publishedvarcount:Int=0varincrementCount:(()->Void)?}structSampleView:View{@ObservedObjectvarprops=ButtonProps()varbody:someView{VStack(alignment:.center,spacing:0){HStack(alignment:.center){Text("Count\(props.count)").padding().scaledToFill().minimumScaleFactor(0.5)}HStack(alignment:.center){Button(action:{self.props.incrementCount?()}){Image(systemName:"plus.circle.fill").foregroundColor(.white).padding().background(LinearGradient(gradient:Gradient(colors:[Color.purple,Color.pink]),startPoint:.top,endPoint:.bottom)).clipShape(Circle())}}}.padding().clipShape(Circle())}}
Enter fullscreen modeExit fullscreen mode

CreateApp_Resources/iOS/src/SampleViewProvider.swift:

importSwiftUI@objcclassSampleViewProvider:UIViewController,SwiftUIProvider{// MARK: INITrequiredinit?(coderaDecoder:NSCoder){super.init(coder:aDecoder)}requiredpublicinit(){super.init(nibName:nil,bundle:nil)}publicoverridefuncviewDidLoad(){super.viewDidLoad()setupSwiftUIView(content:swiftUIView)registerObservers()}// MARK: PRIVATEprivatevarswiftUIView=SampleView()privatefuncregisterObservers(){swiftUIView.props.incrementCount={letcount=self.swiftUIView.props.count+1// update swiftUI viewself.swiftUIView.props.count=count// notify nativescriptself.onEvent?(["count":count])}}// MARK: API/// Receive data from NativeScriptfuncupdateData(data:NSDictionary){ifletcount=data.value(forKey:"count")as?Int{// update swiftUI viewswiftUIView.props.count=count// notify nativescriptself.onEvent?(["count":count])}}/// Send data to NativeScriptvaronEvent:((NSDictionary)->Void)?}
Enter fullscreen modeExit fullscreen mode

Use your SwiftUI in a NativeScript layout

  • app/main-page.xml:
<Pagexmlns="http://schemas.nativescript.org/tns.xsd"xmlns:sw="@nativescript/swift-ui"navigatingTo="navigatingTo"><StackLayout><sw:SwiftUIswiftId="sampleView"data="{{ nativeCount }}"swiftUIEvent="{{ onEvent }}"loaded="{{ loadedSwiftUI }}"/><Labeltext="{{ 'NativeScript Label: ' + nativeCount.count }}"class="h2"/><Buttontext="NativeScript data bindings: Decrement"tap="{{ updateNativeScriptData }}"class="btn btn-primary"/><Buttontext="SwiftUI data bindings: Decrement"tap="{{ updateSwiftData }}"class="btn btn-primary"/></StackLayout></Page>
Enter fullscreen modeExit fullscreen mode
  • app/main-page.ts:
import{registerSwiftUI,UIDataDriver,SwiftUI,SwiftUIEventData,}from"@nativescript/swift-ui";import{EventData,Observable,Page}from"@nativescript/core";// A. You can generate types for your own Swift Provider with 'ns typings ios'// B. Otherwise you can ignore by declaring the class name you know you provideddeclareconstSampleViewProvider:any;registerSwiftUI("sampleView",(view)=>newUIDataDriver(SampleViewProvider.alloc().init(),view));interfaceCountData{count:number;}exportfunctionnavigatingTo(args:EventData){constpage=<Page>args.object;page.bindingContext=newDemoModel();}exportclassDemoModelextendsObservable{swiftui:SwiftUI;nativeCount={count:0,};loadedSwiftUI(args){this.swiftui=args.object;}onEvent(evt:SwiftUIEventData<CountData>){this.set("nativeCount",{count:evt.data.count});}updateNativeScriptData(){this.set('nativeCount',{count:this.nativeCount.count-1});}updateSwiftData(){this.swiftui.updateData({count:this.nativeCount.count-1});}}
Enter fullscreen modeExit fullscreen mode

iOS screen

About Valor Software:

Founded in 2013 byDmitriy Shekhovtsov (Dima) as a MEAN stack software development firm,Valor has evolved into a globally renowned software development and consulting firm with over 130 individuals working on Full Stack development with a primary focus on all things TypeScript from 5 continents.

Media Contact:sales@valor-software.com

Valor Software Logo

Top comments(4)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
vallemar profile image
Juan de Dios Martínez Vallejo
  • Joined

amazing!! I need to try this!

CollapseExpand
 
codewithn profile image
Nandee Tjihero
  • Work
    Dev
  • Joined

Amazing! I just tried it. But why is the view rendered differently in {N} vs direct SwiftUI?
Image description

CollapseExpand
 
codewithn profile image
Nandee Tjihero
  • Work
    Dev
  • Joined

Got it! It's just a matter of adjusting the view's width. Thanks for your awesome work!
Image description

CollapseExpand
 
dgmachado profile image
Douglas Machado
Software Developer
  • Work
    Software Engineer at Valor Software
  • Joined

It's a constraint issue. You should fix the N code to allow the swiftui component expand.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Modernizing the web with Module Federation and Nx

More fromValor Labs

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp