1673503320
PgTyped makes it possible to use raw SQL in TypeScript with guaranteed type-safety.
No need to map or translate your DB schema to TypeScript, PgTyped automatically generates types and interfaces for your SQL queries by using your running Postgres database as the source of type information.
Visit our new documentation page at https://pgtyped.now.sh/
npm install @pgtyped/cli @pgtyped/query typescript
(typescript is a required peer dependency for pgtyped)config.json
file.npx pgtyped -w -c config.json
to start PgTyped in watch mode.Refer to the example app for a preconfigured example.
Lets save some queries in books.sql
:
/* @name FindBookById */
SELECT * FROM books WHERE id = :bookId;
PgTyped parses the SQL file, extracting all queries and generating strictly typed TS queries in books.queries.ts
:
/** Types generated for queries found in "books.sql" */
//...
/** 'FindBookById' parameters type */
export interface IFindBookByIdParams {
bookId: number | null;
}
/** 'FindBookById' return type */
export interface IFindBookByIdResult {
id: number;
rank: number | null;
name: string | null;
author_id: number | null;
}
/**
* Query generated from SQL:
* SELECT * FROM books WHERE id = :bookId
*/
export const findBookById = new PreparedQuery<
IFindBookByIdParams,
IFindBookByIdResult
>(...);
Query findBookById
is now statically typed, with types inferred from the PostgreSQL schema.
This generated query can be imported and executed as follows:
import { Client } from 'pg';
import { findBookById } from './books.queries';
export const client = new Client({
host: 'localhost',
user: 'test',
password: 'example',
database: 'test',
});
async function main() {
await client.connect();
const books = await findBookById.run(
{
bookId: 5,
},
client,
);
console.log(`Book name: ${books[0].name}`);
await client.end();
}
main();
This project is being actively developed and its APIs might change. All issue reports, feature requests and PRs appreciated.
Author: Adelsz
Source Code: https://github.com/adelsz/pgtyped
License: MIT license
1658269800
Il existe plusieurs options pratiques avec NativeScript pour créer l'interface utilisateur de votre application. Vous pouvez utiliser les composants d'interface utilisateur de base du framework qui offrent une bonne base de composants communs dont presque toutes les applications peuvent avoir besoin. Vous pouvez inclure des plugins de plate -forme qui offrent des expériences de vue personnalisées et uniques. Ou vous pouvez créer le vôtre à partir de zéro, ce sur quoi nous allons nous concentrer dans cet article.
Sur iOS, l'architecture de la vue utilise une structure d'héritage bien formalisée et mature appelée UIKit
qui peut être explorée dans la documentation d'Apple ici . La classe de base dont tous héritent est UIView . C'est à partir de cette classe principale et de toute sous-classe que vous pouvez créer des vues NativeScript personnalisées.
Sur Android, l'architecture des vues utilise une structure d'héritage également bien formalisée et mature. Le android.view
package offre le bloc de construction de vue de base, la classe View . Ceci est similaire à iOS et sert de classe de vue de base aux mêmes fins sur Android.
Avec NativeScript, vous obtenez une classe de base également appelée View qui regroupe les deux éléments ci-dessus respectivement pour chaque plate-forme vous permettant de travailler avec seulement 1 API cohérente contre 2 API différentes tout en obtenant les mêmes caractéristiques de performance sur chacune.
Les mécanismes que NativeScript utilise pour fournir cette belle cohérence entre la composition de la vue iOS et Android sont ouverts pour que vous puissiez l'utiliser vous-même, déverrouillant un éventail vertigineux de possibilités créatives pour le développement mobile.
Des vues personnalisées peuvent être créées avec les éléments suivants :
import { View } from 'tns-core-modules/ui/core/view';export class MyCustomView extends View { createNativeView() { /** * required * This must return a native iOS or Android view */ return (UIView || android.view.View); } initNativeView() { // optional } disposeNativeView() { // optional }}
Avec les projets Angular, vous pouvez ensuite enregistrer ce nouvel élément pour l'utiliser. Un bon endroit pour s'inscrire est dans le composant d'application racine de n'importe quelle application Angular :
import { registerElement } from 'nativescript-angular/element-registry';// register custom views for your appregisterElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);@Component({ selector: 'app-root', templateUrl: 'app.component.html',})export class AppComponent {}
Vous êtes désormais libre d'utiliser votre vue native personnalisée n'importe où dans votre application, comme vous pouvez vous y attendre :
<MyCustomView></MyCustomView>
Il convient de noter que vous pouvez utiliser n'importe quelle classe NativeScript comme base de votre vue native personnalisée. Par exemple, si vous vouliez créer un Button personnalisé, vous pourriez étendre le NativeScript Button
ou si vous vouliez créer un conteneur de mise en page personnalisé unique, vous pourriez étendre le NativeScript GridLayout
. Les possibilités sont vastes.
Vous pouvez certainement créer une classe de vue personnalisée et insérer isIOS
ou isAndroid
conditionner comme suit :
createNativeView() { if (isIOS) { return UIView; } else if (isAndroid) { return android.view.View; }}
Ne faites pas ça . Ce serait une mauvaise pratique car il deviendra sans aucun doute difficile à maintenir au fil du temps, sans parler de la facilité d'introduire des bogues de cette façon.
.ios
Au lieu de cela , NativeScript prend en charge un .android
suffixe de nom de fichier pour diviser proprement les fonctionnalités de la plate-forme comme suit :
custom-view.ios.ts
:createNativeView() { return UIView;}
custom-view.android.ts
:createNativeView() { return android.view.View;}
Comme on pouvait s'y attendre, cela provoque maintenant une énigme sur la façon d'importer et d'utiliser réellement une telle division sur le comportement de la plate-forme dans une seule base de code unifiée. C'est là que les fichiers de définition TypeScript sauvent la journée. Pour toute classe fractionnée de plate-forme que vous créez, vous créerez toujours un fichier de définition simple qui expose simplement le nom de la classe pour l'importer dans votre base de code :
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';export declare class MyCustomView extends View {}
Cela vous permet maintenant d'importer comme vous le souhaitez :
import { MyCustomView } from '../path/to/custom-view';
Le plus souvent, lors de l'intégration de vues natives personnalisées ou de la recherche de ce qui est possible pour votre projet, la chose naturelle à faire est de regarder quels plugins de la communauté NativeScript sont disponibles. Si rien n'est trouvé dans la communauté, le prochain endroit où chercher serait les plugins iOS CocoaPod ou Android Gradle qui répondent à vos besoins.
Et si rien ne correspond à mes besoins ?
C'est maintenant que vous créeriez vous-même une vue native personnalisée.
Je vais partager un exemple de celui que j'ai dû construire récemment pour un projet client. En fait, il y avait un plugin communautaire disponible pour ce dont nous avions besoin par l'incroyable maître du plugin Eddy Verbruggen . Nous voulions intégrer la toute nouvelle fonctionnalité Apple SignIn d'iOS 13. Il s'avère qu'Eddy avait fourni un plugin pour cela ici , ce qui était très utile.
Cependant il y avait un problème. Comme la plupart des développeurs mobiles le savent, le processus d'examen des applications d'Apple peut parfois être intimidant et très frustrant. Avec toute implémentation de fonctionnalité iOS, vous souhaitez généralement consulter les directives d'Apple concernant l'utilisation et déterminer si des règles s'appliquent à votre cas d'utilisation. Avec Apple SignIn, leurs docs ont une Guidelines
section spécifique :
Consignes Lorsque vous planifiez et concevez votre application ou votre site Web pour Se connecter avec Apple, assurez-vous de suivre ces consignes : Consignes relatives à l'interface utilisateur Consignes d'examen de l'App Store Consignes d'utilisation pour les sites Web et autres plates-formes Contrat de licence du programme pour développeurs Apple
En particulier , les lignes directrices sur l'interface humaine stipulent ceci :
Pour aider les gens à créer un compte et à se connecter, il est préférable d'utiliser les boutons familiers fournis par Apple pour se connecter avec Apple. Lorsque vous utilisez les API fournies par le système pour créer un bouton Se connecter avec Apple, vous obtenez : Un bouton qui est garanti d'utiliser un titre, une police, une couleur et un style approuvés par Apple L'assurance que le contenu du bouton conserve des proportions idéales lorsque vous modifiez son > style Traduction automatique du titre du bouton dans la langue définie pour > l'appareil Prise en charge de la configuration du rayon d'angle du bouton pour qu'il corresponde au style de votre > interface utilisateur (iOS, macOS et Web) Une étiquette de texte alternative fournie par le système qui permet à VoiceOver décrire le bouton
Le langage ici ressemble à une recommandation/suggestion d'utiliser leurs propres boutons pour vous assurer de ne pas utiliser accidentellement un titre, une police, une couleur et un style non approuvés. Par conséquent, nous ne voulions pas risquer d'être rejetés dans l'App Store pour ne pas avoir utilisé le bon style de bouton approuvé. L'autre chose qui a sauté ici et qui a fini par être un avantage intéressant pour l'utilisation de leur bouton de connexion Apple natif était :
Traduction automatique du titre du bouton dans la langue définie pour l'appareil >
Cette application était internationale et la traduction automatique était un gros bonus, d'autant plus que la chaîne traduisible exacte qu'Apple approuverait pour la connexion est probablement également importante.
Retour au plugin d'Eddy nativescript-apple-sign-in . Nous voulons absolument l'utiliser car il fournit l'implémentation d'authentification que nous aurions autrement dû écrire nous-mêmes. Cependant, il ne fournit pas le composant de bouton de connexion natif qui pourrait devenir un problème sur Apple Review.
Alors construisons-en un.
Nous commençons par faire exactement ce dont nous avons discuté ci-dessus en créant des fichiers fractionnés de plate-forme pour préparer notre composant de vue native personnalisé :
apple-signin-button.ios.ts
:export class AppleSignInButton extends View { createNativeView() { return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0)); }}
apple-signin-button.android.ts
:export class AppleSignInButton extends View { createNativeView() { return new android.widget.LinearLayout(this._context); }}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';export declare class AppleSignInButton extends View {}
Pour la vue iOS, nous commençons avec le bloc de construction de base de toutes les vues iOS comme mentionné, le UIView. Cela montre comment en initialiser un correctement. Respectivement sur Android, nous utilisons un conteneur de mise en page Android natif commun qui prend le context
comme argument fourni par la superclasse de NativeScript View
.
Afin de taper librement avec intellisense contre des API natives iOS et Android pures comme celle-ci, assurez-vous d'installer les fichiers de définition de plate-forme de NativeScript avec ceci :
npm i tns-platform-declarations --save-dev
Vous pouvez ensuite les référencer dans le references.d.ts
fichier racine de vos projets (si vous n'en avez pas, créez simplement ce fichier à la racine de votre projet) avec le contenu suivant :
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
En fait, commencer avec précisément cette configuration au début de la création de votre vue native personnalisée est une excellente façon de commencer. Après avoir enregistré cet élément comme indiqué précédemment, il fonctionnera désormais correctement sur iOS et Android. Vous ne verrez encore rien visuellement car nous n'avons encore rien construit d'unique.
Concentrons nos efforts sur iOS car il ne s'agira que d'une fonctionnalité iOS pour le moment, mais la connexion Android Apple est possible, comme mentionné ici .
Une chose importante toujours avec le développement iOS est de reconnaître les fonctionnalités qui ne peuvent être disponibles que sur certaines versions d'iOS. La connexion Apple n'est disponible qu'à partir d'iOS 13 et versions ultérieures. Heureusement, le plugin d'Eddy fournit une belle méthode booléenne pour vérifier cela.
En utilisant la documentation d'Apple comme référence, nous pouvons implémenter le bouton selon leurs spécifications avec ce qui suit tout en lui permettant de se dégrader gracieusement sur les versions iOS où il n'est pas pris en charge :
import { View } from 'tns-core-modules/ui/core/view';import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;export declare class AppleSignInButton extends View { private _tapHandler: NSObject; createNativeView() { if (isSignInWithAppleSupported()) { const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle( ASAuthorizationAppleIDButtonType.SignIn, ASAuthorizationAppleIDButtonStyle.WhiteOutline, ); nativeView.cornerRadius = 50; this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this)); nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside); return nativeView; } else { return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0)); } } disposeNativeView() { // teardown this._tapHandler = null; super.disposeNativeView(); }}const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend( { tap: function(nativeButton: any, nativeEvent: any) { const owner: AppleSignInButton = nativeButton._owner; if (owner) { owner.notify({ eventName: 'tap', object: owner, }); } }, }, { exposedMethods: { tap: { returns: interop.types.void, params: [interop.types.id, interop.types.id], }, }, },);AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) { const handler = AppleSignInButtonTapHandlerImpl.new(); handler._owner = owner; return handler;};
Il y a beaucoup à décompresser car il utilise des API iOS pures, ce qui est l'une des choses fascinantes et agréables à propos du travail avec NativeScript. La possibilité de coder librement pour la plate-forme que vous construisez sans délai ni tracas et avec le langage de votre choix, vous construisez le reste de votre application entière, TypeScript.
Nous pouvons utiliser ce composant comme ceci :
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
Voici comment cela s'affiche directement dans l'exemple d'application NativeScript :
Je ne couvrirai pas tous les détails ici, mais quelques points à noter :
View
nous sommes en mesure de tirer parti de l' notify
API pour propager un geste iOS purement natif tap
directement via l'API de notre composant pour une liaison de données facile.NSObject
l'utilisation du NSObject.extend({...
modèle qui est généralement plus sûr à utiliser même si vous finissez par décider de compiler votre application vers ES6 - voir ce problème pour plus de compréhensioninterop
pour gérer correctement l'exposition des arguments de la méthode gestuelle native. L' interop
espace de noms "Fournit une API pour travailler avec les types C natifs, les pointeurs, l'arithmétique des pointeurs et la mémoire."declare var ASAuthorizationAppleIDButton
en haut de notre composant. Vous pouvez cependant utiliser les dernières déclarations de plate-forme NativeScript qui fourniraient ces symboles globalement à votre IDE TypeScript. Dans le cas où les types ne sont pas fournis par NativeScript (c'est-à-dire si vous utilisez un plugin tiers non fourni directement par les frameworks iOS), vous pouvez générer des typages pour tous les plugins tiers inclus en exécutant : TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
qui générerait tous les fichiers de définition de type pour votre application dans un typings
dossiernew android.widget.LinearLayout(this._context)
sur Android garantira que l'utilisation de ce composant ne plantera pas notre application lorsque le composant est initialisé sur Android car il createNativeView
est nécessaire de renvoyer une vue native. Il rendra simplement un LinearLayout vide et ne sera donc pas visible.Vous pouvez explorer et exécuter tout le code mentionné dans cet article ici .
Source : https://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658268120
Existem várias opções convenientes com o NativeScript para criar a interface do usuário do seu aplicativo. Você pode usar os principais componentes de interface do usuário do framework, que oferecem uma boa linha de base de componentes comuns que quase todos os aplicativos podem precisar. Você pode incluir plug-ins de plataforma que fornecem experiências de visualização personalizadas e exclusivas. Ou você pode construir o seu próprio do zero, que é o que vamos focar neste artigo.
No iOS, a arquitetura de visualização usa uma estrutura de herança bem formalizada e madura chamada UIKit
que pode ser explorada nos documentos da Apple aqui . A classe base da qual todos herdam é UIView . É a partir dessa classe principal e de qualquer subclasse dela que você pode criar visualizações personalizadas do NativeScript.
No Android, a arquitetura de visualização usa uma estrutura de herança igualmente bem formalizada e madura. O android.view
pacote oferece o bloco de construção básico da visualização, a classe View . Isso é semelhante ao iOS e serve como uma classe de visualização base para os mesmos propósitos no Android.
Com o NativeScript, você obtém uma classe base também chamada View , que agrega ambas as opções acima, respectivamente, para cada plataforma, permitindo que você trabalhe com apenas 1 API consistente versus 2 APIs diferentes, enquanto ainda obtém as mesmas características de desempenho em cada uma.
A mecânica que o NativeScript usa para fornecer essa boa consistência entre a composição de visualização do iOS e do Android está aberta para você usar, desbloqueando uma variedade estonteante de possibilidades criativas para o desenvolvimento móvel.
Visualizações personalizadas podem ser criadas com o seguinte:
import { View } from 'tns-core-modules/ui/core/view';
export class MyCustomView extends View {
createNativeView() {
/**
* required
* This must return a native iOS or Android view
*/
return (UIView || android.view.View);
}
initNativeView() {
// optional
}
disposeNativeView() {
// optional
}
}
Com projetos Angular você pode registrar este novo elemento para uso. Um bom lugar para se registrar é no componente de aplicativo raiz de qualquer aplicativo Angular:
import { registerElement } from 'nativescript-angular/element-registry';
// register custom views for your app
registerElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {}
Agora você está livre para usar sua visualização nativa personalizada em qualquer lugar do seu aplicativo, como você pode esperar:
<MyCustomView></MyCustomView>
Vale a pena notar que você pode usar qualquer classe NativeScript como base de sua visualização nativa personalizada. Por exemplo, se você quiser criar um Button personalizado, poderá estender o NativeScript's Button
ou se desejar criar um contêiner de layout personalizado exclusivo, poderá estender o NativeScript's GridLayout
. As possibilidades são vastas.
Você certamente pode criar 1 classe de exibição personalizada e inserir isIOS
ou isAndroid
condicionais como as seguintes:
createNativeView() {
if (isIOS) {
return UIView;
} else if (isAndroid) {
return android.view.View;
}
}
Não faça isso . Isso seria uma má prática, pois sem dúvida se tornará difícil de manter ao longo do tempo, além de ser fácil introduzir bugs dessa maneira.
Em vez disso, o NativeScript suporta um sufixo .ios
de .android
nome de arquivo para dividir a funcionalidade da plataforma de forma limpa, como a seguir:
custom-view.ios.ts
:createNativeView() {
return UIView;
}
custom-view.android.ts
:createNativeView() {
return android.view.View;
}
Como se poderia esperar, isso agora causa um enigma sobre como realmente importar e usar essa divisão no comportamento da plataforma em uma única base de código unificada. É aqui que os arquivos de definição do TypeScript salvam o dia. Para qualquer classe de divisão de plataforma que você criar, você sempre criará um arquivo de definição simples que apenas expõe o nome da classe para importação em toda a sua base de código:
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class MyCustomView extends View {}
Isso agora permite que você importe como desejar:
import { MyCustomView } from '../path/to/custom-view';
Na maioria das vezes, ao integrar visualizações nativas personalizadas ou pesquisar o que pode ser possível para o seu projeto, a coisa natural a fazer é verificar quais plug-ins da comunidade NativeScript estão disponíveis. Se nada for encontrado na comunidade, o próximo lugar a procurar seria os plugins iOS CocoaPod ou Android Gradle que atendem às suas necessidades.
E se nada atender às minhas necessidades?
Agora é onde você construiria uma visualização nativa personalizada.
Vou compartilhar um exemplo de um que tive que construir recentemente para um projeto de cliente. Na verdade, havia um plugin comunitário disponível para o que precisávamos pelo incrível mestre de plugins Eddy Verbruggen . Queríamos integrar o novo recurso iOS 13 Apple SignIn. Acontece que Eddy forneceu um plugin para isso aqui que foi muito útil.
No entanto, havia um problema. Como a maioria dos desenvolvedores de dispositivos móveis sabe, o processo de revisão de aplicativos da Apple pode às vezes ser intimidante e altamente frustrante. Com qualquer implementação de recurso do iOS, você geralmente deseja revisar as diretrizes da Apple sobre o uso e se alguma regra pertence ao seu caso de uso. Com o Apple SignIn, seus documentos têm uma Guidelines
seção específica :
Diretrizes Ao planejar e projetar seu aplicativo ou site para Entrar com a Apple, certifique-se de seguir estas diretrizes: Diretrizes de interface humana Diretrizes de revisão da App Store Diretrizes de uso para sites e outras plataformas Contrato de licença do Apple Developer Program
Em particular, as Diretrizes de Interface Humana afirmam o seguinte:
Para ajudar as pessoas a configurar uma conta e entrar, é melhor usar os botões familiares que a Apple fornece para Entrar com a Apple. Ao usar as APIs fornecidas pelo sistema para criar um botão Entrar com a Apple, você obtém: Um botão com garantia de uso de título, fonte, cor e estilo aprovados pela Apple. > estilo Tradução automática do título do botão para o idioma definido para o > dispositivo Suporte para configurar o raio do canto do botão para corresponder ao estilo da sua interface do usuário > (iOS, macOS e web) Um rótulo de texto alternativo fornecido pelo sistema que permite que o VoiceOver descreva o botão
A linguagem aqui soa como uma recomendação/sugestão para usar seus próprios botões para garantir que você não use acidentalmente um título, fonte, cor e estilo não aprovados. Portanto, não queríamos correr o risco de ser rejeitados na App Store por não usar o estilo de botão aprovado correto. A outra coisa que surgiu aqui, que acabou sendo um bom benefício para usar o botão Apple SignIn nativo, foi:
Tradução automática do título do botão para o idioma definido para o > dispositivo
Este aplicativo era internacional e ter tradução automática foi um grande bônus, especialmente considerando que a string traduzível exata que a Apple aprovaria para o login provavelmente também é importante.
De volta ao plugin do Eddy nativescript-apple-sign-in . Nós absolutamente queremos usar isso, pois fornece a implementação de autenticação que, de outra forma, teríamos que escrever nós mesmos. No entanto, ele não fornece o componente do botão SignIn nativo que pode se tornar um problema no Apple Review.
Então vamos construir um.
Começamos fazendo exatamente o que discutimos acima, criando arquivos de divisão de plataforma para preparar nosso componente de exibição nativa personalizado:
apple-signin-button.ios.ts
:export class AppleSignInButton extends View {
createNativeView() {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
apple-signin-button.android.ts
:export class AppleSignInButton extends View {
createNativeView() {
return new android.widget.LinearLayout(this._context);
}
}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class AppleSignInButton extends View {}
Para a visualização do iOS, começamos com o bloco de construção básico de todas as visualizações do iOS, conforme mencionado, o UIView. Isso mostra como iniciar um corretamente. Respectivamente no Android, usamos um contêiner de layout Android nativo comum que usa context
o argumento que é convenientemente fornecido pela View
superclasse do NativeScript.
Para digitar livremente com intellisense contra APIs nativas puras de iOS e Android como esta, certifique-se de instalar os arquivos de definição de plataforma do NativeScript com isto:
npm i tns-platform-declarations --save-dev
Você pode então referenciá-los no references.d.ts
arquivo raiz do seu projeto (se você não tiver um, basta criar este arquivo na raiz do seu projeto) com o seguinte conteúdo:
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
Na verdade, começar exatamente com essa configuração ao iniciar sua construção de visualização nativa personalizada é uma ótima maneira de começar. Depois de registrar este elemento, conforme mostrado anteriormente, ele agora será executado corretamente no iOS e no Android. Você ainda não verá nada visualmente porque ainda não construímos nada único.
Vamos concentrar nossos esforços no iOS, pois esse será um recurso apenas do iOS no momento, no entanto, o Android Apple Sign In é possível, conforme mencionado aqui .
Uma coisa importante sempre com o desenvolvimento do iOS é reconhecer recursos que podem estar disponíveis apenas em determinadas versões do iOS. O Apple Sign In está disponível apenas a partir do iOS 13 e superior. Felizmente, o plugin do Eddy fornece um bom método booleano para verificar isso.
Usando os documentos da Apple como referência , podemos implementar o botão de acordo com suas especificações com o seguinte, além de permitir que ele se degrade graciosamente nas versões do iOS onde não é suportado:
import { View } from 'tns-core-modules/ui/core/view';
import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';
declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;
export declare class AppleSignInButton extends View {
private _tapHandler: NSObject;
createNativeView() {
if (isSignInWithAppleSupported()) {
const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle(
ASAuthorizationAppleIDButtonType.SignIn,
ASAuthorizationAppleIDButtonStyle.WhiteOutline,
);
nativeView.cornerRadius = 50;
this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this));
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
return nativeView;
} else {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
disposeNativeView() {
// teardown
this._tapHandler = null;
super.disposeNativeView();
}
}
const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend(
{
tap: function(nativeButton: any, nativeEvent: any) {
const owner: AppleSignInButton = nativeButton._owner;
if (owner) {
owner.notify({
eventName: 'tap',
object: owner,
});
}
},
},
{
exposedMethods: {
tap: {
returns: interop.types.void,
params: [interop.types.id, interop.types.id],
},
},
},
);
AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) {
const handler = AppleSignInButtonTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
Há muito o que descompactar lá, pois está usando APIs iOS puras, que é uma das coisas fascinantes e agradáveis de trabalhar com NativeScript. A capacidade de codificar livremente para a plataforma que você está construindo sem demora ou problemas e com a linguagem de escolha você está construindo o resto de seu aplicativo inteiro, TypeScript.
Podemos usar este componente assim:
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
Veja como isso é renderizado diretamente no aplicativo de amostra NativeScript:
Não vou cobrir todos os detalhes aqui, no entanto, algumas coisas devem ser observadas:
View
, podemos aproveitar a notify
API para propagar um gesto iOS puramente nativo tap
diretamente para a API do nosso componente para facilitar a vinculação de dadosNSObject
usando o NSObject.extend({...
padrão que geralmente é mais seguro de usar, mesmo se você decidir compilar seu aplicativo para ES6 - veja este problema para mais compreensãointerop
namespace do NativeScript para lidar adequadamente com a exposição de argumentos do método de gesto nativo. O interop
namespace “Fornece uma API para trabalhar com tipos nativos C, ponteiros, aritmética de ponteiro e memória”.declare var ASAuthorizationAppleIDButton
na parte superior do nosso componente. No entanto, você pode usar as declarações mais recentes da plataforma NativeScript que forneceriam esses símbolos globalmente ao seu IDE do TypeScript. Caso os tipos não sejam fornecidos pelo NativeScript (ou seja, se estiver usando um plug-in de terceiros não fornecido diretamente pelas estruturas do iOS), você pode gerar tipagens para qualquer plug-in de terceiros incluído executando: TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
o que geraria todos os arquivos de definição de tipo para seu aplicativo dentro de uma typings
pastanew android.widget.LinearLayout(this._context)
no Android garantirá que o uso desse componente não travará nosso aplicativo quando o componente for inicializado no Android, pois createNativeView
é necessário retornar uma visualização nativa. Ele simplesmente renderizará um LinearLayout vazio, portanto, não seria visível.Você pode explorar e executar todo o código mencionado neste artigo aqui .
Fonte: https://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658266200
NativeScript 有几个方便的选项来构建应用程序的用户界面。您可以使用框架的核心 ui 组件,这些组件提供了几乎每个应用程序都可能需要的通用组件的良好基线。您可以包含提供自定义和独特视图体验的平台插件。或者您可以从头开始构建自己的,这就是我们将在本文中重点介绍的内容。
在 iOS 上,视图架构使用了一种形式化且成熟的继承结构,可以在此处的 Apple 文档UIKit
中进行探索。所有继承自的基类是UIView。您可以从这个核心类和它的任何子类构建自定义 NativeScript 视图。
在 Android 上,视图架构使用了类似的形式化且成熟的继承结构。该android.view
包提供了基本的视图构建块View类。这与 iOS 类似,并在 Android 上用作用于相同目的的基本视图类。
使用 NativeScript,您将获得一个也称为View的基类,它分别为每个平台汇总上述两者,允许您仅使用 1 个一致的 api 与 2 个不同的 api,同时仍然在每个平台上实现相同的性能特征。
NativeScript 用于在 iOS 和 Android 视图组合之间提供这种良好一致性的机制是开放的,您可以使用自己为移动开发解锁一系列令人眼花缭乱的创意可能性。
可以使用以下内容创建自定义视图:
import { View } from 'tns-core-modules/ui/core/view';
export class MyCustomView extends View {
createNativeView() {
/**
* required
* This must return a native iOS or Android view
*/
return (UIView || android.view.View);
}
initNativeView() {
// optional
}
disposeNativeView() {
// optional
}
}
然后,您可以使用 Angular 项目注册这个新元素以供使用。注册的好地方是任何 Angular 应用程序的根应用程序组件:
import { registerElement } from 'nativescript-angular/element-registry';
// register custom views for your app
registerElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {}
您现在可以在您的应用程序的任何地方自由使用您的自定义原生视图,正如您所期望的那样:
<MyCustomView></MyCustomView>
值得注意的是,您可以使用任何NativeScript 类作为自定义原生视图的基础。例如,如果你想构建一个自定义 Button,你可以扩展 NativeScript 的Button
,或者如果你想创建一个独特的自定义布局容器,你可以扩展 NativeScript 的GridLayout
. 可能性是巨大的。
您当然可以构建 1 个自定义视图类并插入isIOS
或isAndroid
条件如下:
createNativeView() {
if (isIOS) {
return UIView;
} else if (isAndroid) {
return android.view.View;
}
}
不要这样做。这将是一种不好的做法,因为随着时间的推移,它无疑会变得难以维护,更不用说容易以这种方式引入错误。
相反,NativeScript 支持.ios
和.android
文件名后缀来干净地拆分平台功能,如下所示:
custom-view.ios.ts
:createNativeView() {
return UIView;
}
custom-view.android.ts
:createNativeView() {
return android.view.View;
}
正如人们可能预期的那样,这现在导致了一个难题,即如何在单个统一代码库中实际导入和使用这种平台行为上的拆分。这是 TypeScript 定义文件节省时间的地方。对于您创建的任何平台拆分类,您将始终创建一个简单的定义文件,该文件仅公开类名以在整个代码库中导入:
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class MyCustomView extends View {}
现在,您可以根据需要导入:
import { MyCustomView } from '../path/to/custom-view';
大多数情况下,在集成自定义原生视图或研究项目的可能性时,自然要做的就是查看可用的 NativeScript 社区插件。如果在社区中找不到任何东西,那么下一个地方就是寻找适合您需求的iOS CocoaPod或Android Gradle插件。
如果没有什么适合我的需要怎么办?
现在是您自己构建自定义原生视图的地方。
我将分享一个我最近为客户项目构建的示例。事实上,出色的插件大师Eddy Verbruggen提供了一个社区插件来满足我们的需求。我们想要集成全新的 iOS 13 Apple 登录功能。原来 Eddy 在这里为此提供了一个插件,非常有帮助。
然而有一个问题。正如大多数移动开发人员所知,Apple 的应用程序审查过程有时可能令人生畏,也可能令人沮丧。对于任何 iOS 功能实现,您通常都需要查看 Apple 关于使用的指南以及是否有任何规则与您的用例相关。使用 Apple SignIn,他们的文档有一个特定的Guidelines
部分:
指南 在为 Sign in with Apple 计划和设计应用程序或网站时,请确保遵循以下指南: 人机界面指南 App Store Review Guidelines 网站和其他平台使用指南 Apple 开发者计划许可协议
特别是人机界面指南规定了这一点:
为帮助人们设置帐户并登录,最好使用 Apple 为使用 Apple 登录提供的熟悉按钮。当您使用系统提供的 API 创建“使用 Apple 登录”按钮时,您将获得: 保证使用 Apple 认可的标题、字体、颜色和样式的按钮> style 将按钮的标题自动翻译成为设备设置的语言 支持配置按钮的圆角半径以匹配 UI 的样式 >(iOS、macOS 和 web)系统提供的替代文本标签,允许 VoiceOver描述按钮
这里的语言听起来像是建议/建议使用他们自己的按钮,以确保您不会意外使用未经批准的标题、字体、颜色和样式。因此,我们不想冒着被 App Store 拒绝的风险,因为没有使用正确的批准按钮样式。在这里跳出来的另一件事最终成为使用他们的原生 Apple SignIn 按钮的一个很好的好处是:
将按钮的标题自动翻译成为 > 设备设置的语言
这个应用程序是国际化的,自动翻译是一个很大的好处,特别是考虑到苹果批准登录的确切可翻译字符串可能也很重要。
回到 Eddy 的插件nativescript-apple-sign-in。我们绝对希望使用它,因为它提供了我们必须自己编写的身份验证实现。但是,它不提供可能成为 Apple Review 问题的本机登录按钮组件。
所以让我们建立一个。
我们首先通过创建平台拆分文件来准备我们的自定义本机视图组件,从而完全按照我们上面讨论的方式开始:
apple-signin-button.ios.ts
:export class AppleSignInButton extends View {
createNativeView() {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
apple-signin-button.android.ts
:export class AppleSignInButton extends View {
createNativeView() {
return new android.widget.LinearLayout(this._context);
}
}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class AppleSignInButton extends View {}
对于 iOS 视图,我们从前面提到的所有 iOS 视图的基本构建块 UIView 开始。这显示了如何正确初始化一个。分别在 Android 上,我们使用一个通用的原生Android 布局容器,它以context
NativeScript 的View
超类方便地提供的参数作为参数。
为了像这样使用智能感知对纯 iOS 和 Android 原生 api 进行自由输入,请务必安装 NativeScript 的平台定义文件:
npm i tns-platform-declarations --save-dev
然后,您可以在项目根references.d.ts
文件中引用它们(如果没有,只需在项目的根目录中创建此文件),其中包含以下内容:
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
事实上,在开始您的自定义原生视图构建时,精确地从这个设置开始是一个很好的开始方式。如前所示注册此元素后,它现在可以在 iOS 和 Android 上正常运行。你还不会在视觉上看到任何东西,因为我们还没有构建任何独特的东西。
让我们将精力集中在 iOS 上,因为目前这将是 iOS 唯一的功能,但是这里提到的 Android Apple 登录是可能的。
iOS 开发中的一件重要事情是识别可能仅在特定版本的 iOS 上可用的功能。Apple 登录仅从 iOS 13 及更高版本开始可用。幸运的是,Eddy 的插件提供了一个很好的布尔方法来检查这一点。
使用Apple 的文档作为参考,我们可以根据他们的规范实现按钮,同时还允许它在不支持的 iOS 版本上正常降级:
import { View } from 'tns-core-modules/ui/core/view';
import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';
declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;
export declare class AppleSignInButton extends View {
private _tapHandler: NSObject;
createNativeView() {
if (isSignInWithAppleSupported()) {
const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle(
ASAuthorizationAppleIDButtonType.SignIn,
ASAuthorizationAppleIDButtonStyle.WhiteOutline,
);
nativeView.cornerRadius = 50;
this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this));
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
return nativeView;
} else {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
disposeNativeView() {
// teardown
this._tapHandler = null;
super.disposeNativeView();
}
}
const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend(
{
tap: function(nativeButton: any, nativeEvent: any) {
const owner: AppleSignInButton = nativeButton._owner;
if (owner) {
owner.notify({
eventName: 'tap',
object: owner,
});
}
},
},
{
exposedMethods: {
tap: {
returns: interop.types.void,
params: [interop.types.id, interop.types.id],
},
},
},
);
AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) {
const handler = AppleSignInButtonTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
那里有很多东西要解压,因为它使用纯 iOS api,这是与 NativeScript 一起工作的迷人和愉快的事情之一。能够为您正在构建的平台自由编码,而无需延迟或麻烦,并使用您正在构建整个应用程序的其余部分 TypeScript 所选择的语言。
我们可以像这样使用这个组件:
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
这是在 NativeScript 示例应用程序中直接呈现的方式:
我不会在这里介绍所有细节,但有几点需要注意:
View
,我们能够利用notify
api 将纯原生 iOStap
手势直接传播到我们组件的 api,以便于数据绑定NSObject
使用该NSObject.extend({...
模式,即使您最终决定将您的应用程序编译为 ES6,它通常使用起来也更安全 - 请参阅此问题以获得更多理解interop
命名空间来正确处理暴露的本机手势方法参数。命名空间“interop
为使用原生 C 类型、指针、指针算术和内存提供 API。”declare var ASAuthorizationAppleIDButton
在这个例子中,我们在组件顶部使用了一个快速的 TypeScript 快捷方式。但是,您可以使用最新的 NativeScript 平台声明,它将全局提供这些符号到您的 TypeScript IDE。如果 NativeScript 未提供类型(即,如果使用 iOS 框架未直接提供的 3rd 方插件),您可以通过运行以下命令为任何包含的 3rd 方插件生成类型:TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
这将为您生成所有类型定义文件typings
文件夹内的应用程序new android.widget.LinearLayout(this._context)
在 Android 上返回的事实将确保在 Android 上初始化该组件时使用该组件不会使我们的应用程序崩溃,因为createNativeView
它需要返回一个原生视图。它只会简单地呈现一个空的 LinearLayout,因此不可见。您可以在此处探索和运行本文中提到的所有代码。
来源:https ://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658262600
アプリのユーザーインターフェイスを構築するためのNativeScriptにはいくつかの便利なオプションがあります。ほとんどすべてのアプリが必要とする可能性のある一般的なコンポーネントの優れたベースラインを提供するフレームワークのコアUIコンポーネントを使用できます。カスタムでユニークなビューエクスペリエンスを提供するプラットフォームプラグインを含めることができます。または、この記事で焦点を当てる、独自のゼロから構築することもできます。
iOSでは、ビューアーキテクチャは、よく形式化された成熟した継承構造を使用します。これは、 AppleのドキュメントでUIKit
調べることができます。すべてが継承する基本クラスはUIViewです。カスタムNativeScriptビューを作成できるのは、このコアクラスとそのサブクラスからです。
Androidでは、ビューアーキテクチャは、同様に形式化された成熟した継承構造を使用します。このandroid.view
パッケージは、基本的なビュービルディングブロックであるViewクラスを提供します。これはiOSに似ており、Androidで同じ目的のベースビュークラスとして機能します。
NativeScriptを使用すると、Viewとも呼ばれる基本クラスを取得します。これは、プラットフォームごとに上記の両方をそれぞれロールアップし、それぞれで同じパフォーマンス特性を達成しながら、1つの一貫したAPIと2つの異なるAPIで作業できるようにします。
NativeScriptがiOSとAndroidの両方のビュー構成の間にこの優れた一貫性を提供するために使用するメカニズムは、モバイル開発に創造的な可能性の目まぐるしい配列を解き放つためにあなた自身を使用するために開かれています。
カスタムビューは、次の方法で作成できます。
import { View } from 'tns-core-modules/ui/core/view';
export class MyCustomView extends View {
createNativeView() {
/**
* required
* This must return a native iOS or Android view
*/
return (UIView || android.view.View);
}
initNativeView() {
// optional
}
disposeNativeView() {
// optional
}
}
Angularプロジェクトでは、この新しい要素を登録して使用できます。登録するのに適した場所は、Angularアプリのルートアプリコンポーネントです。
import { registerElement } from 'nativescript-angular/element-registry';
// register custom views for your app
registerElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {}
これで、予想どおり、アプリ内のどこでもカスタムネイティブビューを自由に使用できます。
<MyCustomView></MyCustomView>
カスタムネイティブビューのベースとして任意のNativeScriptクラスを使用できることに注意してください。たとえば、カスタムボタンをButton
作成する場合は、NativeScriptを拡張できます。また、独自のカスタムレイアウトコンテナを作成する場合は、NativeScriptを拡張できますGridLayout
。可能性は広大です。
確かに、1つのカスタムビュークラスを作成し、次のような挿入isIOS
またはisAndroid
条件を設定できます。
createNativeView() {
if (isIOS) {
return UIView;
} else if (isAndroid) {
return android.view.View;
}
}
これをしないでください。この方法でバグを簡単に導入できることは言うまでもなく、時間の経過とともに保守が困難になることは間違いないため、これは悪い習慣になります。
代わりに、NativeScriptは、プラットフォーム機能を次のようにきれいに分割するためのファイル名サフィックスをサポートし.ios
て.android
います。
custom-view.ios.ts
:createNativeView() {
return UIView;
}
custom-view.android.ts
:createNativeView() {
return android.view.View;
}
予想されるように、これにより、単一の統合コードベースでプラットフォームの動作に関するこのような分割を実際にインポートして使用する方法についての難問が発生します。これは、TypeScript定義ファイルが1日を節約する場所です。作成するプラットフォーム分割クラスでは、コードベース全体にインポートするためのクラス名を公開するだけの単純な定義ファイルを常に作成します。
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class MyCustomView extends View {}
これにより、必要に応じてインポートできるようになりました。
import { MyCustomView } from '../path/to/custom-view';
ほとんどの場合、カスタムネイティブビューを統合したり、プロジェクトで何が可能かを調査したりする場合、自然なことは、利用可能なNativeScriptコミュニティプラグインを確認することです。コミュニティから何も見つからない場合、次に探す場所は、ニーズに合ったiOSCocoaPodまたはAndroidGradleプラグインです。
私のニーズに合うものがない場合はどうなりますか?
ここで、カスタムネイティブビューを自分で作成します。
クライアントプロジェクトのために最近構築しなければならなかったものの例を共有します。実際、すばらしいプラグインマスターであるEddyVerbruggenが必要としていたものに利用できるコミュニティプラグインがありました。まったく新しいiOS13Appleサインイン機能を統合したかったのです。Eddyがここにプラグインを提供していたことがわかりました。これは非常に役に立ちました。
しかし問題がありました。ほとんどのモバイル開発者が知っているように、Appleのアプリレビュープロセスは、時には威圧的であるだけでなく、非常に苛立たしいものになる可能性があります。iOSの機能を実装する場合は、通常、使用法に関するAppleのガイドラインと、ユースケースに関連するルールがあるかどうかを確認する必要があります。Apple SignInを使用すると、ドキュメントに特定のGuidelines
セクションがあります。
ガイドラインAppleでサインインするためのアプリまたはWebサイトを計画および設計するときは、次のガイドラインに必ず従ってください。ヒューマンインターフェイスガイドラインAppStoreレビューガイドラインWebサイトおよびその他のプラットフォームの使用ガイドラインAppleDeveloperProgramライセンス契約
特に、ヒューマンインターフェイスガイドラインには次のように記載されています。
人々がアカウントを設定してサインインするのを助けるために、AppleがAppleでサインインするために提供するおなじみのボタンを使用するのが最善です。システム提供のAPIを使用して「Appleでサインイン」ボタンを作成すると、次のようになります。Appleが承認したタイトル、フォント、色、スタイルを使用することが保証されているボタンボタンの内容を変更しても、ボタンの内容が理想的な比率を維持することが保証されます。 >styleボタンのタイトルをデバイスに設定されている言語に自動翻訳>UIのスタイルに一致するようにボタンの角の半径を構成するためのサポート>(iOS、macOS、およびWeb)VoiceOverを可能にするシステム提供の代替テキストラベルボタンを説明する
ここでの言語は、承認されていないタイトル、フォント、色、スタイルを誤って使用しないように、独自のボタンを使用することを推奨/提案しているように聞こえます。したがって、適切な承認済みボタンスタイルを使用していないために、AppStoreで拒否されるリスクを冒したくありませんでした。ここに飛び出したもう1つのことは、ネイティブのAppleSignInボタンを使用することの大きなメリットになりました。
>デバイスに設定されている言語へのボタンのタイトルの自動翻訳
このアプリは国際的であり、自動翻訳があることは大きなボーナスでした。特に、Appleがサインインのために承認する正確な翻訳可能な文字列を考慮すると、同様に重要である可能性があります。
Eddyのプラグインnativescript-apple-sign-inに戻ります。これは、他の方法では自分で作成する必要がある認証実装を提供するため、絶対に使用したいと思います。ただし、AppleReviewで問題になる可能性のあるネイティブのサインインボタンコンポーネントは提供されていません。
それでは、1つ作成しましょう。
まず、プラットフォーム分割ファイルを作成してカスタムネイティブビューコンポーネントを準備することにより、上記で説明したことを正確に実行します。
apple-signin-button.ios.ts
:export class AppleSignInButton extends View {
createNativeView() {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
apple-signin-button.android.ts
:export class AppleSignInButton extends View {
createNativeView() {
return new android.widget.LinearLayout(this._context);
}
}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class AppleSignInButton extends View {}
iOSビューの場合、前述のすべてのiOSビューの基本的な構成要素であるUIViewから始めます。これは、1つを正しく初期化する方法を示しています。それぞれAndroidでは、 NativeScriptのスーパークラスによって便利に提供される引数としてを使用する一般的なネイティブAndroidレイアウトコンテナを使用します。contextView
このような純粋なiOSおよびAndroidネイティブAPIに対してインテリセンスで自由に入力するには、NativeScriptのプラットフォーム定義ファイルを次のようにインストールしてください。
npm i tns-platform-declarations --save-dev
次に、プロジェクトのルートreferences.d.ts
ファイル(プロジェクトのルートにこのファイルを作成するだけの場合)で、次の内容でそれらを参照できます。
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
実際、カスタムネイティブビューの構築を開始するときに正確にこの設定から始めることは、開始するのに最適な方法です。前に示したようにこの要素を登録すると、iOSとAndroidの両方で正しく実行されるようになります。まだユニークなものを構築していないため、視覚的にはまだ何も表示されません。
これは現時点ではiOSのみの機能であるため、iOSに焦点を当てましょう。ただし、ここで説明するように、AndroidAppleサインインは可能です。
iOS開発で常に重要なことの1つは、特定のバージョンのiOSでのみ使用できる機能を認識することです。Appleサインインは、iOS13以降でのみ使用できます。幸いなことに、Eddyのプラグインは、これをチェックするための優れたブール型のメソッドを提供します。
Appleのドキュメントを参照として使用すると、次の仕様に従ってボタンを実装できます。また、サポートされていないiOSバージョンではボタンを正常に劣化させることができます。
import { View } from 'tns-core-modules/ui/core/view';
import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';
declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;
export declare class AppleSignInButton extends View {
private _tapHandler: NSObject;
createNativeView() {
if (isSignInWithAppleSupported()) {
const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle(
ASAuthorizationAppleIDButtonType.SignIn,
ASAuthorizationAppleIDButtonStyle.WhiteOutline,
);
nativeView.cornerRadius = 50;
this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this));
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
return nativeView;
} else {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
disposeNativeView() {
// teardown
this._tapHandler = null;
super.disposeNativeView();
}
}
const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend(
{
tap: function(nativeButton: any, nativeEvent: any) {
const owner: AppleSignInButton = nativeButton._owner;
if (owner) {
owner.notify({
eventName: 'tap',
object: owner,
});
}
},
},
{
exposedMethods: {
tap: {
returns: interop.types.void,
params: [interop.types.id, interop.types.id],
},
},
},
);
AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) {
const handler = AppleSignInButtonTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
純粋なiOSAPIを使用しているため、ここで解凍するものはたくさんあります。これは、NativeScriptを使用することの魅力的で楽しいものの1つです。構築しているプラットフォームを遅滞なく、または面倒なく自由にコーディングでき、選択した言語を使用して、アプリ全体の残りの部分であるTypeScriptを構築できます。
このコンポーネントは次のように使用できます。
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
これがNativeScriptサンプルアプリで直接レンダリングされる方法は次のとおりです。
ここではすべての詳細をカバーするわけではありませんが、注意すべき点がいくつかあります。
View
を拡張することで、APIを利用してnotify
、純粋にネイティブなiOStap
ジェスチャをコンポーネントのAPIに直接伝播し、データバインディングを容易にすることができます。NSObject
使用して拡張するための代替構文を使用しています。詳細については、この問題を参照してください。NSObject.extend({...
interop
名前空間を使用して、ネイティブジェスチャメソッド引数の公開を適切に処理しています。名前interop
空間は、「ネイティブC型、ポインター、ポインター演算、およびメモリーを操作するためのAPIを提供します。」declare var ASAuthorizationAppleIDButton
この例では、コンポーネントの上部でを使用して、簡単なTypeScriptショートカットを使用しています。ただし、これらのシンボルをTypeScriptIDEにグローバルに提供する最新のNativeScriptプラットフォーム宣言を使用できます。タイプがNativeScriptによって提供されていない場合(つまり、iOSフレームワークによって直接提供されていないサードパーティプラグインを使用している場合)、実行することで、含まれているサードパーティプラグインのタイピングを生成TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
できます。typings
フォルダ内のアプリnew android.widget.LinearLayout(this._context)
、コンポーネントがAndroidで初期化されたときに、このコンポーネントを使用してもアプリがクラッシュしないことが保証されます。createNativeView
空のLinearLayoutをレンダリングするだけなので、表示されません。ここで、この記事に記載されているすべてのコードを調べて実行できます。
ソース:https ://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658262600
Có một số tùy chọn thuận tiện với NativeScript để xây dựng giao diện người dùng cho ứng dụng của bạn. Bạn có thể sử dụng các thành phần ui cốt lõi của khung công tác cung cấp một đường cơ sở tốt đẹp về các thành phần phổ biến mà hầu hết mọi ứng dụng có thể cần. Bạn có thể bao gồm các plugin nền tảng cung cấp trải nghiệm xem tùy chỉnh và độc đáo. Hoặc bạn có thể xây dựng của riêng bạn từ đầu, đó là những gì chúng tôi sẽ tập trung vào trong bài viết này.
Trên iOS, kiến trúc khung nhìn sử dụng một cấu trúc kế thừa được chính thức hóa và trưởng thành được gọi là cấu trúc UIKit
có thể được khám phá trong tài liệu của Apple tại đây . Lớp cơ sở mà tất cả kế thừa từ đó là UIView . Từ lớp lõi này và bất kỳ lớp con nào của nó mà bạn có thể xây dựng các chế độ xem NativeScript tùy chỉnh.
Trên Android, kiến trúc khung nhìn sử dụng cấu trúc kế thừa đã được chính thức hóa và hoàn thiện tương tự. Gói android.view
này cung cấp khối xây dựng khung nhìn cơ bản, lớp View . Điều này tương tự như iOS và đóng vai trò như một lớp chế độ xem cơ sở cho các mục đích tương tự trên Android.
Với NativeScript, bạn sẽ nhận được một lớp cơ sở cũng được gọi là View , lớp này cuộn lên cả hai lớp trên tương ứng cho mỗi nền tảng, cho phép bạn làm việc chỉ với 1 api nhất quán so với 2 api khác nhau trong khi vẫn đạt được các đặc tính hiệu suất giống nhau trên mỗi nền tảng.
Cơ chế mà NativeScript sử dụng để cung cấp sự nhất quán tốt đẹp này giữa thành phần chế độ xem cả iOS và Android mở cho bạn sử dụng để mở khóa khả năng sáng tạo chóng mặt cho sự phát triển trên thiết bị di động.
Chế độ xem tùy chỉnh có thể được tạo bằng cách sau:
import { View } from 'tns-core-modules/ui/core/view';
export class MyCustomView extends View {
createNativeView() {
/**
* required
* This must return a native iOS or Android view
*/
return (UIView || android.view.View);
}
initNativeView() {
// optional
}
disposeNativeView() {
// optional
}
}
Với các dự án Angular, bạn có thể đăng ký phần tử mới này để sử dụng. Một nơi tốt để đăng ký là trong thành phần ứng dụng gốc của bất kỳ ứng dụng Angular nào:
import { registerElement } from 'nativescript-angular/element-registry';
// register custom views for your app
registerElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {}
Giờ đây, bạn có thể tự do sử dụng chế độ xem gốc tùy chỉnh của mình ở bất kỳ đâu trong ứng dụng như bạn có thể mong đợi:
<MyCustomView></MyCustomView>
Cần lưu ý rằng bạn có thể sử dụng bất kỳ lớp NativeScript nào làm cơ sở cho chế độ xem gốc tùy chỉnh của mình. Ví dụ: nếu bạn muốn tạo một Nút tùy chỉnh, bạn có thể mở rộng NativeScript Button
hoặc nếu bạn muốn tạo một vùng chứa bố cục tùy chỉnh độc đáo, bạn có thể mở rộng NativeScript GridLayout
. Khả năng là rất lớn.
Bạn chắc chắn có thể xây dựng 1 lớp chế độ xem tùy chỉnh và chèn isIOS
hoặc isAndroid
các điều kiện như sau:
createNativeView() {
if (isIOS) {
return UIView;
} else if (isAndroid) {
return android.view.View;
}
}
Đừng làm điều này . Đây sẽ là một thực tiễn không tốt vì nó chắc chắn sẽ trở nên khó duy trì theo thời gian, chưa kể đến việc dễ dàng đưa ra các lỗi theo cách này.
Thay vào đó, NativeScript hỗ trợ .ios
và .android
hậu tố tên tệp để phân chia chức năng nền tảng một cách rõ ràng như sau:
custom-view.ios.ts
:createNativeView() {
return UIView;
}
custom-view.android.ts
:createNativeView() {
return android.view.View;
}
Như người ta có thể mong đợi, điều này hiện gây ra một câu hỏi hóc búa về cách thực sự nhập và sử dụng sự phân chia như vậy trên hành vi nền tảng trong một cơ sở mã thống nhất duy nhất. Đây là nơi các tệp định nghĩa TypeScript lưu trong ngày. Đối với bất kỳ lớp phân chia nền tảng nào bạn tạo, bạn sẽ luôn tạo một tệp định nghĩa đơn giản chỉ hiển thị tên lớp để nhập trong toàn bộ cơ sở mã của bạn:
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class MyCustomView extends View {}
Điều này bây giờ cho phép bạn nhập như bạn muốn:
import { MyCustomView } from '../path/to/custom-view';
Thông thường, khi tích hợp các chế độ xem gốc tùy chỉnh hoặc nghiên cứu những gì có thể có cho dự án của bạn, điều tự nhiên cần làm là xem xét những plugin cộng đồng NativeScript có sẵn. Nếu không tìm thấy gì từ cộng đồng, nơi tiếp theo để tìm sẽ dành cho các plugin CocoaPod của iOS hoặc Android Gradle phù hợp với nhu cầu của bạn.
Nếu không có gì phù hợp với nhu cầu của tôi thì sao?
Bây giờ là nơi bạn có thể tự mình xây dựng một chế độ xem gốc tùy chỉnh.
Tôi sẽ chia sẻ một ví dụ về một ví dụ mà tôi đã phải xây dựng gần đây cho một dự án khách hàng. Trên thực tế, có một plugin cộng đồng có sẵn cho những gì chúng tôi cần bởi bậc thầy plugin tuyệt vời Eddy Verbruggen . Chúng tôi muốn tích hợp tính năng Đăng nhập Apple trên iOS 13 hoàn toàn mới. Hóa ra Eddy đã cung cấp một plugin cho việc này ở đây , rất hữu ích.
Tuy nhiên có một vấn đề. Như hầu hết các nhà phát triển di động đều biết, quy trình đánh giá ứng dụng của Apple đôi khi có thể đáng sợ cũng như rất khó chịu. Với bất kỳ triển khai tính năng iOS nào, bạn thường muốn xem lại các nguyên tắc của Apple về cách sử dụng và liệu có bất kỳ quy tắc nào liên quan đến trường hợp sử dụng của bạn hay không. Với Apple SignIn, tài liệu của họ có một Guidelines
phần cụ thể :
Nguyên tắc Khi bạn lập kế hoạch và thiết kế ứng dụng hoặc trang web của mình để Đăng nhập với Apple, hãy đảm bảo tuân theo các nguyên tắc sau: Nguyên tắc về giao diện con người Nguyên tắc đánh giá trên App Store Nguyên tắc sử dụng cho các trang web và các nền tảng khác Thỏa thuận cấp phép chương trình dành cho nhà phát triển của Apple
Cụ thể, Nguyên tắc về Giao diện Con người nêu rõ điều này:
Để giúp mọi người thiết lập tài khoản và đăng nhập, tốt nhất bạn nên sử dụng các nút quen thuộc mà Apple cung cấp cho Đăng nhập với Apple. Khi bạn sử dụng các API do hệ thống cung cấp để tạo nút Đăng nhập bằng Apple, bạn sẽ nhận được: Một nút được đảm bảo sử dụng tiêu đề, phông chữ, màu sắc và kiểu được Apple phê duyệt Đảm bảo rằng nội dung của nút duy trì tỷ lệ lý tưởng khi bạn thay đổi > style Dịch tự động tiêu đề của nút sang ngôn ngữ được đặt cho thiết bị> Hỗ trợ định cấu hình bán kính góc của nút để phù hợp với kiểu giao diện người dùng của bạn> (iOS, macOS và web) Nhãn văn bản thay thế do hệ thống cung cấp cho phép VoiceOver mô tả nút
Ngôn ngữ ở đây giống như một đề xuất / gợi ý sử dụng nút của riêng họ để đảm bảo bạn không vô tình sử dụng tiêu đề, phông chữ, màu sắc và phong cách chưa được phê duyệt. Do đó, chúng tôi không muốn có nguy cơ bị từ chối trong App Store vì không sử dụng đúng kiểu nút đã được phê duyệt. Một điều khác xuất hiện ở đây mà cuối cùng đã trở thành một lợi ích tuyệt vời khi sử dụng nút Đăng nhập Apple gốc của họ là:
Bản dịch tự động tiêu đề của nút sang ngôn ngữ được đặt cho> thiết bị
Ứng dụng này là quốc tế và có bản dịch tự động là một phần thưởng lớn, đặc biệt là khi xem xét chuỗi có thể dịch chính xác mà Apple sẽ chấp thuận cho đăng nhập cũng có thể quan trọng.
Quay lại plugin nativescript-apple-sign-in của Eddy . Chúng tôi hoàn toàn muốn sử dụng điều này vì nó cung cấp triển khai xác thực mà nếu không, chúng tôi sẽ phải tự viết. Tuy nhiên, nó không cung cấp thành phần nút SignIn gốc có thể trở thành một vấn đề trên Apple Review.
Vì vậy, hãy xây dựng một cái.
Chúng tôi bắt đầu bằng cách thực hiện chính xác những gì chúng tôi đã thảo luận ở trên bằng cách tạo các tệp phân chia nền tảng để chuẩn bị cho thành phần chế độ xem gốc tùy chỉnh của chúng tôi:
apple-signin-button.ios.ts
:export class AppleSignInButton extends View {
createNativeView() {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
apple-signin-button.android.ts
:export class AppleSignInButton extends View {
createNativeView() {
return new android.widget.LinearLayout(this._context);
}
}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class AppleSignInButton extends View {}
Đối với chế độ xem iOS, chúng tôi bắt đầu với khối xây dựng cơ bản của tất cả các chế độ xem iOS như đã đề cập, UIView. Điều này cho thấy làm thế nào để init một đúng cách. Tương tự như vậy trên Android, chúng tôi sử dụng một vùng chứa bố cục Android gốc chung , lấy tham context
số này làm đối số được cung cấp một cách thuận tiện bởi lớp cha của NativeScript View
.
Để gõ tự do với intellisense dựa trên các api gốc của iOS và Android thuần túy như thế này, hãy đảm bảo cài đặt các tệp định nghĩa nền tảng của NativeScript với:
npm i tns-platform-declarations --save-dev
Sau đó, bạn có thể tham chiếu chúng trong references.d.ts
tệp gốc dự án của mình (nếu bạn không có, chỉ cần tạo tệp này trong thư mục gốc của dự án) với nội dung sau:
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
Trên thực tế, bắt đầu với thiết lập chính xác này khi bắt đầu xây dựng chế độ xem gốc tùy chỉnh của bạn là một cách tuyệt vời để bắt đầu. Sau khi đăng ký phần tử này như được hiển thị trước đó, bây giờ nó sẽ chạy bình thường trên cả iOS và Android. Bạn sẽ không nhìn thấy bất cứ thứ gì trực quan bởi vì chúng tôi chưa tạo ra bất kỳ thứ gì độc đáo.
Hãy tập trung nỗ lực của chúng tôi vào iOS vì đây sẽ là tính năng duy nhất của iOS tại thời điểm hiện tại, tuy nhiên Đăng nhập bằng Apple trên Android vẫn có thể thực hiện được như đã đề cập ở đây .
Một điều quan trọng luôn xảy ra với quá trình phát triển iOS là nhận dạng các tính năng có thể chỉ có trên một số phiên bản iOS nhất định. Đăng nhập Apple chỉ khả dụng bắt đầu từ iOS 13 trở lên. May mắn thay, plugin của Eddy cung cấp một phương pháp boolean hay để kiểm tra điều này.
Sử dụng tài liệu của Apple làm tài liệu tham khảo , chúng tôi có thể triển khai nút theo thông số kỹ thuật của họ với các thông số sau đồng thời cho phép nó giảm cấp một cách duyên dáng trên các phiên bản iOS không được hỗ trợ:
import { View } from 'tns-core-modules/ui/core/view';
import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';
declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;
export declare class AppleSignInButton extends View {
private _tapHandler: NSObject;
createNativeView() {
if (isSignInWithAppleSupported()) {
const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle(
ASAuthorizationAppleIDButtonType.SignIn,
ASAuthorizationAppleIDButtonStyle.WhiteOutline,
);
nativeView.cornerRadius = 50;
this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this));
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
return nativeView;
} else {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
disposeNativeView() {
// teardown
this._tapHandler = null;
super.disposeNativeView();
}
}
const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend(
{
tap: function(nativeButton: any, nativeEvent: any) {
const owner: AppleSignInButton = nativeButton._owner;
if (owner) {
owner.notify({
eventName: 'tap',
object: owner,
});
}
},
},
{
exposedMethods: {
tap: {
returns: interop.types.void,
params: [interop.types.id, interop.types.id],
},
},
},
);
AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) {
const handler = AppleSignInButtonTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
Có rất nhiều thứ để giải nén ở đó vì nó sử dụng api iOS thuần túy, đây là một trong những điều thú vị và thú vị khi làm việc với NativeScript. Khả năng viết mã tự do cho nền tảng bạn đang xây dựng mà không bị chậm trễ hoặc phức tạp và với ngôn ngữ lựa chọn, bạn đang xây dựng phần còn lại của toàn bộ ứng dụng của mình, TypeScript.
Chúng tôi có thể sử dụng thành phần này như sau:
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
Đây là cách điều này hiển thị trực tiếp trong ứng dụng mẫu NativeScript:
Tôi sẽ không trình bày mọi chi tiết ở đây, tuy nhiên có một số điều cần lưu ý:
View
chúng tôi có thể tận dụng notify
api để truyền bá một cử chỉ iOS thuần túy gốc tap
trực tiếp thông qua api của thành phần của chúng tôi để dễ dàng liên kết dữ liệuNSObject
bằng cách sử dụng NSObject.extend({...
mẫu thường an toàn hơn để sử dụng ngay cả khi bạn quyết định biên dịch ứng dụng của mình sang ES6 - hãy xem vấn đề này để hiểu thêminterop
để xử lý chính xác việc hiển thị các đối số của phương thức cử chỉ gốc. Không interop
gian tên “Cung cấp một API để làm việc với các kiểu C, con trỏ, số học con trỏ và bộ nhớ.”declare var ASAuthorizationAppleIDButton
ở trên cùng của thành phần của chúng tôi. Tuy nhiên, bạn có thể sử dụng các khai báo nền tảng NativeScript mới nhất sẽ cung cấp các ký hiệu đó trên toàn cầu cho IDE TypeScript của bạn. Trong trường hợp các kiểu không được cung cấp bởi NativeScript (tức là, nếu sử dụng plugin của bên thứ 3 không được cung cấp trực tiếp bởi các khung iOS), bạn có thể tạo các kiểu đánh máy cho bất kỳ plugin nào của bên thứ 3 đi kèm bằng cách chạy: thao TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
tác này sẽ tạo tất cả các tệp định nghĩa kiểu cho của bạn ứng dụng bên trong một typings
thư mụcnew android.widget.LinearLayout(this._context)
trên Android sẽ đảm bảo rằng việc sử dụng thành phần này sẽ không làm ứng dụng của chúng tôi gặp sự cố khi thành phần được khởi chạy trên Android vì createNativeView
bắt buộc phải trả lại chế độ xem gốc. Nó sẽ chỉ hiển thị một LinearLayout trống do đó sẽ không hiển thị.Bạn có thể khám phá và chạy tất cả mã được đề cập trong bài viết này tại đây .
Nguồn: https://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658260800
Hay varias opciones convenientes con NativeScript para construir la interfaz de usuario de su aplicación. Puede usar los componentes básicos de la interfaz de usuario del marco que ofrecen una buena base de componentes comunes que casi todas las aplicaciones pueden necesitar. Puede incluir complementos de plataforma que brinden experiencias de visualización únicas y personalizadas. O puede crear uno propio desde cero, que es en lo que nos vamos a centrar en este artículo.
En iOS, la arquitectura de vista utiliza una estructura de herencia madura y bien formalizada UIKit
que se puede explorar en los documentos de Apple aquí . La clase base de la que todos heredan es UIView . Es a partir de esta clase principal y de cualquier subclase que puede crear vistas de NativeScript personalizadas.
En Android, la arquitectura de vista utiliza una estructura de herencia madura y bien formalizada de manera similar. El android.view
paquete ofrece el componente básico de vista, la clase Vista . Esto es similar a iOS y sirve como clase de vista base para los mismos propósitos en Android.
Con NativeScript, obtiene una clase base también llamada Vista , que reúne los dos elementos anteriores respectivamente para cada plataforma, lo que le permite trabajar con solo 1 API consistente frente a 2 API diferentes y, al mismo tiempo, lograr las mismas características de rendimiento en cada una.
La mecánica que utiliza NativeScript para proporcionar esta agradable consistencia entre la composición de vistas de iOS y Android está abierta para que usted mismo la use desbloqueando una vertiginosa variedad de posibilidades creativas para el desarrollo móvil.
Las vistas personalizadas se pueden crear con lo siguiente:
import { View } from 'tns-core-modules/ui/core/view';
export class MyCustomView extends View {
createNativeView() {
/**
* required
* This must return a native iOS or Android view
*/
return (UIView || android.view.View);
}
initNativeView() {
// optional
}
disposeNativeView() {
// optional
}
}
Con los proyectos de Angular, puede registrar este nuevo elemento para su uso. Un buen lugar para registrarse es en el componente de la aplicación raíz de cualquier aplicación Angular:
import { registerElement } from 'nativescript-angular/element-registry';
// register custom views for your app
registerElement('MyCustomView', () => require('../path/to/custom-view').MyCustomView);
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
})
export class AppComponent {}
Ahora puede usar su vista nativa personalizada en cualquier lugar de su aplicación, como es de esperar:
<MyCustomView></MyCustomView>
Vale la pena señalar que puede usar cualquier clase de NativeScript como base de su vista nativa personalizada. Por ejemplo, si quisiera crear un botón personalizado, podría extender el de NativeScript Button
o si quisiera crear un contenedor de diseño personalizado único, podría extender el de NativeScript GridLayout
. Las posibilidades son amplias.
Sin duda, podría crear 1 clase de vista personalizada e insertar isIOS
o isAndroid
condicionales como los siguientes:
createNativeView() {
if (isIOS) {
return UIView;
} else if (isAndroid) {
return android.view.View;
}
}
No hagas esto . Esta sería una mala práctica, ya que sin duda será difícil de mantener con el tiempo, sin mencionar que es fácil introducir errores de esta manera.
.ios
En cambio , NativeScript admite un .android
sufijo de nombre de archivo para dividir la funcionalidad de la plataforma limpiamente como la siguiente:
custom-view.ios.ts
:createNativeView() {
return UIView;
}
custom-view.android.ts
:createNativeView() {
return android.view.View;
}
Como era de esperar, esto ahora causa un enigma sobre cómo importar y usar realmente una división de este tipo en el comportamiento de la plataforma en una única base de código unificada. Aquí es donde los archivos de definición de TypeScript salvan el día. Para cualquier clase dividida de plataforma que cree, siempre creará un archivo de definición simple que solo expone el nombre de la clase para importarlo en su base de código:
custom-view.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class MyCustomView extends View {}
Esto ahora te permite importar como quieras:
import { MyCustomView } from '../path/to/custom-view';
La mayoría de las veces, cuando se integran vistas nativas personalizadas o se investiga lo que puede ser posible para su proyecto, lo más natural es ver qué complementos de la comunidad NativeScript están disponibles. Si no se encuentra nada de la comunidad, el siguiente lugar para buscar sería los complementos de iOS CocoaPod o Android Gradle que se adapten a sus necesidades.
¿Qué pasa si nada se adapta a mis necesidades?
Ahora es donde usted mismo crearía una vista nativa personalizada.
Compartiré un ejemplo de uno que tuve que construir recientemente para un proyecto de cliente. De hecho, había un complemento de la comunidad disponible para lo que necesitábamos por el increíble maestro de complementos Eddy Verbruggen . Queríamos integrar la nueva función Apple SignIn de iOS 13. Resulta que Eddy proporcionó un complemento para esto aquí que fue muy útil.
Sin embargo, había un problema. Como saben la mayoría de los desarrolladores móviles, el proceso de revisión de aplicaciones de Apple puede ser a veces intimidante y muy frustrante. Con cualquier implementación de funciones de iOS, generalmente desea revisar las pautas de Apple sobre el uso y si alguna regla se aplica a su caso de uso. Con Apple SignIn, sus documentos tienen una Guidelines
sección específica :
Directrices Mientras planifica y diseña su aplicación o sitio web para Iniciar sesión con Apple, asegúrese de seguir estas directrices: Directrices de interfaz humana Directrices de revisión de App Store Directrices de uso para sitios web y otras plataformas Acuerdo de licencia del Programa para desarrolladores de Apple
En particular, las Pautas de interfaz humana establecen esto:
Para ayudar a las personas a configurar una cuenta e iniciar sesión, es mejor usar los botones familiares que proporciona Apple para Iniciar sesión con Apple. Cuando usa las API proporcionadas por el sistema para crear un botón Iniciar sesión con Apple, obtiene: Un botón que garantiza usar un título, fuente, color y estilo aprobados por Apple La garantía de que el contenido del botón mantiene proporciones ideales a medida que cambia su > estilo Traducción automática del título del botón al idioma configurado para el > dispositivo Compatibilidad para configurar el radio de la esquina del botón para que coincida con el estilo de su interfaz de usuario > (iOS, macOS y web) Una etiqueta de texto alternativa proporcionada por el sistema que permite que VoiceOver describir el botón
El lenguaje aquí suena como una recomendación/sugerencia para usar sus propios botones para asegurarse de no usar accidentalmente un título, fuente, color y estilo no aprobados. Por lo tanto, no queríamos arriesgarnos a ser rechazados en la App Store por no usar el estilo de botón aprobado correcto. La otra cosa que saltó a la vista aquí y que terminó siendo un buen beneficio para usar su botón nativo de inicio de sesión de Apple fue:
Traducción automática del título del botón al idioma configurado para el > dispositivo
Esta aplicación era internacional y tener traducción automática fue una gran ventaja, especialmente teniendo en cuenta que la cadena traducible exacta que Apple aprobaría para iniciar sesión probablemente también sea importante.
Volver al complemento de Eddy nativescript-apple-sign-in . Absolutamente queremos usar esto, ya que proporciona la implementación de autenticación que, de lo contrario, tendríamos que escribir nosotros mismos. Sin embargo, no proporciona el componente de botón de inicio de sesión nativo que podría convertirse en un problema en Apple Review.
Así que construyamos uno.
Comenzamos haciendo exactamente lo que discutimos anteriormente al crear archivos divididos de plataforma para preparar nuestro componente de vista nativo personalizado:
apple-signin-button.ios.ts
:export class AppleSignInButton extends View {
createNativeView() {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
apple-signin-button.android.ts
:export class AppleSignInButton extends View {
createNativeView() {
return new android.widget.LinearLayout(this._context);
}
}
apple-signin-button.d.ts
:import { View } from 'tns-core-modules/ui/core/view';
export declare class AppleSignInButton extends View {}
Para la vista de iOS, comenzamos con el componente básico de todas las vistas de iOS, como se mencionó, la UIView. Esto muestra cómo iniciar uno correctamente. Respectivamente, en Android, usamos un contenedor de diseño nativo común de Android que toma context
como el argumento que proporciona convenientemente la View
superclase de NativeScript.
Para escribir libremente con intellisense contra API nativas puras de iOS y Android como esta, asegúrese de instalar los archivos de definición de plataforma de NativeScript con esto:
npm i tns-platform-declarations --save-dev
Luego puede hacer referencia a ellos en el references.d.ts
archivo raíz de su proyecto (si no tiene uno, simplemente cree este archivo en la raíz de su proyecto) con los siguientes contenidos:
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/android-19.d.ts" />
De hecho, comenzar precisamente con esta configuración al comenzar la construcción de su vista nativa personalizada es una excelente manera de comenzar. Después de registrar este elemento como se muestra anteriormente, ahora se ejecutará correctamente tanto en iOS como en Android. Todavía no verá nada visualmente porque aún no hemos construido nada único.
Centremos nuestros esfuerzos en iOS, ya que esta será una característica exclusiva de iOS en este momento, sin embargo, es posible iniciar sesión en Android Apple como se menciona aquí .
Una cosa importante siempre con el desarrollo de iOS es reconocer las características que pueden estar disponibles solo en ciertas versiones de iOS. Apple Sign In solo está disponible a partir de iOS 13 y superior. Afortunadamente, el complemento de Eddy proporciona un buen método booleano para verificar esto.
Usando los documentos de Apple como referencia , podemos implementar el botón de acuerdo con sus especificaciones con lo siguiente y al mismo tiempo permitir que se degrade con gracia en las versiones de iOS donde no es compatible:
import { View } from 'tns-core-modules/ui/core/view';
import { isSignInWithAppleSupported } from 'nativescript-apple-sign-in';
declare var ASAuthorizationAppleIDButton, ASAuthorizationAppleIDButtonType, ASAuthorizationAppleIDButtonStyle;
export declare class AppleSignInButton extends View {
private _tapHandler: NSObject;
createNativeView() {
if (isSignInWithAppleSupported()) {
const nativeView = ASAuthorizationAppleIDButton.buttonWithTypeStyle(
ASAuthorizationAppleIDButtonType.SignIn,
ASAuthorizationAppleIDButtonStyle.WhiteOutline,
);
nativeView.cornerRadius = 50;
this._tapHandler = AppleSignInButtonTapHandlerImpl.initWithOwner(new WeakRef(this));
nativeView.addTargetActionForControlEvents(this._tapHandler, 'tap', UIControlEvents.TouchUpInside);
return nativeView;
} else {
return UIView.alloc().initWithFrame(CGRectMake(0, 0, 0, 0));
}
}
disposeNativeView() {
// teardown
this._tapHandler = null;
super.disposeNativeView();
}
}
const AppleSignInButtonTapHandlerImpl = (<any>NSObject).extend(
{
tap: function(nativeButton: any, nativeEvent: any) {
const owner: AppleSignInButton = nativeButton._owner;
if (owner) {
owner.notify({
eventName: 'tap',
object: owner,
});
}
},
},
{
exposedMethods: {
tap: {
returns: interop.types.void,
params: [interop.types.id, interop.types.id],
},
},
},
);
AppleSignInButtonTapHandlerImpl['initWithOwner'] = function(owner: WeakRef<AppleSignInButton>) {
const handler = AppleSignInButtonTapHandlerImpl.new();
handler._owner = owner;
return handler;
};
Hay mucho que desempaquetar allí, ya que utiliza API de iOS puras, lo cual es una de las cosas fascinantes y agradables de trabajar con NativeScript. La capacidad de codificar libremente para la plataforma que está creando sin demoras ni problemas y con el lenguaje de su elección está creando el resto de su aplicación completa, TypeScript.
Podemos usar este componente así:
<AppleSignInButton (tap)="appleSignInAction($event)"></AppleSignInButton>
Así es como esto se representa directamente en la aplicación de muestra de NativeScript:
No cubriré todos los detalles aquí, sin embargo, un par de cosas a tener en cuenta:
View
, podemos aprovechar la notify
API para propagar un gesto de iOS puramente nativo tap
directamente a través de la API de nuestro componente para facilitar el enlace de datos.NSObject
el uso del NSObject.extend({...
patrón, que generalmente es más seguro de usar, incluso si termina decidiendo compilar su aplicación en ES6. Consulte este problema para obtener más información.interop
para manejar correctamente la exposición de argumentos de métodos de gestos nativos. El interop
espacio de nombres "Proporciona una API para trabajar con tipos de C nativos, punteros, aritmética de punteros y memoria".declare var ASAuthorizationAppleIDButton
en la parte superior de nuestro componente. Sin embargo, puede usar las últimas declaraciones de la plataforma NativeScript que proporcionarían esos símbolos globalmente a su IDE de TypeScript. En el caso de que NativeScript no proporcione los tipos (es decir, si usa un complemento de terceros no proporcionado directamente por los marcos de trabajo de iOS), puede generar tipos para cualquier complemento de terceros incluido ejecutando: TNS_TYPESCRIPT_DECLARATIONS_PATH="$(pwd)/typings" tns build ios
lo que generaría todos los archivos de definición de tipo para su aplicación dentro de una typings
carpetanew android.widget.LinearLayout(this._context)
a Android garantizará que el uso de este componente no bloquee nuestra aplicación cuando el componente se inicialice en Android, ya createNativeView
que se requiere para devolver una vista nativa. Simplemente representará un LinearLayout vacío, por lo tanto, no será visible.Puede explorar y ejecutar todo el código mencionado en este artículo aquí .
Fuente: https://ultimatecourses.com/blog/custom-native-view-components-nativescript
1658243417
There are several convenient options with NativeScript to build your app’s user interface. You can use the framework’s core ui components which offer a nice baseline of common components almost every app may need. You can include platform plugins which provide custom and unique view experiences. Or you can build your own from scratch which is what we’re going to focus on in this article.
On iOS, the view architecture uses a well formalized and mature inheritance structure called UIKit
which can be explored in Apple’s docs here. The base class which all inherit from is UIView. It’s from this core class and any subclass to it that you can build custom NativeScript views.
On Android, the view architecture uses a similarly well formalized and mature inheritance structure. The android.view
package offers the basic view building block, the View class. This is similar to iOS and serves as a base view class for the same purposes on Android.
With NativeScript you get a base class also called View which rolls up both of the above respectively for each platform allowing you to work with just 1 consistent api vs. 2 different api’s while still achieving the same performance characteristics on each.
See more at: https://ultimatecourses.com/blog/custom-native-view-components-nativescript
1654240010
A NativeScript Pager / Carousel component that allows the user to swipe left and right through pages of data.
![]() | ![]() |
---|---|
iOS Demo | Android Demo |
Run the following command from the root of your project:
ns plugin add @nativescript-community/ui-pager
Property | Type |
---|---|
items | array or ItemsSource |
selectedIndex | number |
canGoRight | boolean |
canGoLeft | boolean |
spacing | PercentLengthType |
peaking | PercentLengthType |
perPage | number |
indicator | string ('disable', 'none', 'worm', 'fill', 'swap', 'thin_worm', 'flat') |
circularMode | boolean |
autoPlayDelay | number |
autoPlay | boolean |
orientation | string ('horizontal' or 'vertical') |
autoPlay | boolean |
disableSwipe | boolean |
showIndicator | boolean |
indicatorColor | Color or string |
indicatorSelectedColor | Color or string |
Pager for NativeScript supports the core ObservableArray module part of the core NativeScript modules collection. Using an ObservableArray instance as a source for Pager will ensure that changes in the source collection will be automatically taken care of by the control.
Property | Type |
---|---|
items | array or ItemsSource |
selectedIndex | number |
canGoRight | boolean |
canGoLeft | boolean |
spacing | PercentLengthType |
peaking | PercentLengthType |
perPage | number |
indicator | string ('disable', 'none', 'worm', 'fill', 'swap', 'thin_worm', 'flat') |
circularMode | boolean |
autoPlayDelay | number |
autoPlay | boolean |
orientation | string ('horizontal' or 'vertical') |
autoPlay | boolean |
disableSwipe | boolean |
showIndicator | boolean |
indicatorColor | Color or string |
indicatorSelectedColor | Color or string |
Event | Type |
---|---|
selectedIndexChange | { object: View, propertyName: string, oldValue: any, value: any } |
scroll | { object: View, selectedIndex: number, currentPosition: number, scrollX: number, scrollY: number } |
swipe | { object: View } |
swipeStart | { object: View } |
swipeOver | { object: View } |
swipeEnd | { object: View } |
loadMoreItems | { object: View } |
itemLoading | { object: View, android: any, ios: any, index: number, view: View } |
itemDisposing (iOS only) | { object: View, android: any, ios: any, index: number, view: View } |
Import the module into your project.
import { PagerModule } from "@nativescript-community/ui-pager/angular";
@NgModule({
imports: [
PagerModule,
],
})
Import the module into your project.
import { Pager } from '@nativescript-community/ui-pager/react';
Import the module into your project.
import { registerNativeViewElement } from 'svelte-native/dom';
import PagerElement from '@nativescript-community/ui-pager/svelte';
import { PagerItem } from '@nativescript-community/ui-pager';
PagerElement.register();
registerNativeViewElement('pageritem', () => PagerItem);
Import the module into your project.
import Vue from 'nativescript-vue';
import Pager from '@nativescript-community/ui-pager/vue';
Vue.use(Pager);
To run the demos, you must clone this repo recursively.
git clone https://github.com/@nativescript-community/ui-pager.git --recursive
Install Dependencies:
npm i # or 'yarn install' or 'pnpm install'
Interactive Menu:
To start the interactive menu, run npm start
(or yarn start
or pnpm start
). This will list all of the commonly used scripts.
npm run build
npm run build.angular # or for Angular
npm run demo.[ng|react|svelte|vue].[ios|android]
npm run demo.svelte.ios # Example
If you have any questions/issues/comments please feel free to create an issue or start a conversation in the NativeScript Community Discord.
Author: nativescript-community
Download Link: Download The Source Code
Official Website: https://github.com/nativescript-community/ui-pager
License: Apache-2.0 license
1654238857
NativeScript plugin for checkbox.
![]() | ![]() |
---|---|
iOS Demo | Android Demo |
Run the following command from the root of your project:
ns plugin add @nativescript-community/ui-checkbox
Android | iOS |
---|---|
Android CheckBox | BEMCheckBox |
circle
on iOS and square
on Android? Just make the boxType
value conditional.checked
property when this event fires to see the new value.<Page
xmlns="http://schemas.nativescript.org/tns.xsd"
xmlns:CheckBox="@nstudio/nativescript-checkbox" loaded="pageLoaded">
<ActionBar title="Native Checkbox" />
<StackLayout>
<CheckBox:CheckBox checked="checkProp" text="myCheckText" fillColor="myCheckColor" id="myCheckbox" />
<CheckBox:CheckBox text="CheckBox Label" checked="false" />
</StackLayout>
</Page>
import { CheckBox } from '@nstudio/nativescript-checkbox';
import { topmost } from '@nativescript/core/ui/frame';
public toggleCheck() {
const checkBox = topmost().getViewById('yourCheckBoxId');
checkBox.toggle();
}
public getCheckProp() {
const checkBox = topmost().getViewById('yourCheckBoxId');
console.log('checked prop value = ' + checkBox.checked);
}
import { TNSCheckBoxModule } from '@nstudio/nativescript-checkbox/angular';
@NgModule({
imports: [TNSCheckBoxModule]
// etc.
})
export class YourModule {}
// component:
export class SomeComponent {
@ViewChild('CB1') FirstCheckBox: ElementRef;
constructor() {}
public toggleCheck() {
this.FirstCheckBox.nativeElement.toggle();
}
public getCheckProp() {
console.log(
'checked prop value = ' + this.FirstCheckBox.nativeElement.checked
);
}
}
<StackLayout>
<CheckBox #CB1 text="CheckBox Label" checked="false"></CheckBox>
<button (tap)="toggleCheck()" text="Toggle it!"></button>
<button (tap)="getCheckProp()" text="Check Property"></button>
</StackLayout>
In your main.js
(The file where the root Vue instance is created) register the element
Vue.registerElement(
'CheckBox',
() => require('@nstudio/nativescript-checkbox').CheckBox,
{
model: {
prop: 'checked',
event: 'checkedChange'
}
}
);
And in your template, use it as:
<check-box :checked="isChecked" @checkedChange="isChecked = $event.value" />
Use checked
instead of v-model
. See #99.
This repository includes Angular, Vue.js, and Svelte demos. In order to run these execute the following in your shell:
$ git clone https://github.com/@nativescript-community/ui-checkbox
$ cd ui-checkbox
$ npm i
$ npm run setup
$ npm run build # && npm run build.angular
$ cd demo-ng # or demo-vue or demo-svelte
$ ns run ios|android
To run the demos, you must clone this repo recursively.
git clone https://github.com/@nativescript-community/ui-checkbox.git --recursive
Install Dependencies:
npm i # or 'yarn install' or 'pnpm install'
Interactive Menu:
To start the interactive menu, run npm start
(or yarn start
or pnpm start
). This will list all of the commonly used scripts.
npm run build
npm run build.angular # or for Angular
npm run demo.[ng|react|svelte|vue].[ios|android]
npm run demo.svelte.ios # Example
If you have any questions/issues/comments please feel free to create an issue or start a conversation in the NativeScript Community Discord.
Author: nativescript-community
Download Link: Download The Source Code
Official Website: https://github.com/nativescript-community/ui-checkbox
License: View license
1649276880
¿Se ha preguntado alguna vez: "¿Hasta qué punto podré desarrollar el código fuente completo de mi aplicación y complementos de NativeScript?". Es probable que ya sepa que el marco NativeScript le brinda acceso completo a la API de la plataforma nativa (iOS/Android) . Eso está muy bien, pero ¿qué significa eso para la situación futura ineludible en la que se le asignará la tarea de depurar ese error del "caso de la esquina" y tendrá que echar un vistazo debajo del capó y profundizar en el Objective-C/ nativo? ¿Código Java de su código de complemento? La respuesta a esta pregunta es un rotundo "¡Sí, se puede!" . Pero ¿qué pasa con la siguiente pregunta, "¿Cómo?".
Esta es la pregunta que intentaré responder y presentarle un nuevo enfoque para depurar el código fuente nativo del código de su complemento.
Hoy quiero presentarles nativescript-dev-debugging
, un paquete npm que pueden descargar:
npm i nativescript-dev-debugging --save-dev
Este paquete no se parece a ningún otro paquete npm de NativeScript en el sentido de que no proporciona ninguna interfaz de usuario, comportamientos o compilación/paquete de código para su aplicación. Pero proporciona algo que se describe mejor como un flujo de trabajo . Ok, puede preguntar "¿Qué es un flujo de trabajo?".
Un flujo de trabajo consiste en un patrón orquestado y repetible de actividad comercial habilitado por la organización sistemática de recursos en procesos que transforman materiales, brindan servicios o procesan información. ( wikipedia )
Esto es absolutamente lo que nativescript-dev-debugging
proporciona, específicamente para la tarea de depurar un complemento de NativeScript . En su funcionalidad principal, el paquete básicamente realiza los siguientes cinco pasos por usted:
.aar
archivo y un .framework
archivo y tiene su código fuente (que creó un equipo nativo diferente de iOS y Android)El producto final de la secuencia anterior es un "flujo de trabajo" que puede usar para mejorar su experiencia de desarrollo mientras trabaja en un complemento de NativeScript. Un ejemplo simple de dicho complemento es el tns-core-modules
complemento que consume el complemento, que simplemente contiene los archivos tns-core-modules-widgets
preconstruidos ..aar.framework
Vale, si has llegado hasta aquí, debes estar preguntándote: "Vale, lo entiendo, las 'cosas' deben reconstruirse, pero ¿cómo es eso un 'flujo de trabajo'?". Bueno, este es el mejor momento para describir cómo y por qué nativescript-dev-debugging
se creó la idea de un paquete como este.
Internamente en el equipo de NativeScript, una de las cosas que el 99% de la gente ha estado haciendo es cambiar el código nativo de una biblioteca utilizada en un complemento (recuerde que en NativeScript todo es un complemento), reconstruir manualmente ese código, mover manualmente el producto de esa compilación en el directorio de plataformas de complementos y active manualmente una compilación de la aplicación NS que se utiliza para probar una funcionalidad nueva o reparada. Como puede ver, hay mucho "manualmente" en este flujo de trabajo, por lo que la idea era "¿Qué pasa si podemos automatizar esto 'manualmente' para que todo el equipo de NativeScript use el mismo enfoque mientras hace su trabajo diario en el marco? ”. Esto significaría que todos los equipos serán más productivos y permitirá una colaboración más fácil porque todos sabrán los pasos de cómo se hacen las cosas.
Naturalmente, después de haber decidido hacer algo para unificar y automatizar este flujo de trabajo, inmediatamente decidimos poner este resultado a disposición de toda la comunidad de NativeScript, para que podamos ayudar a cualquier persona que enfrente tales tareas a hacer su trabajo más rápido y más fácil, e incluso demostrar que cambiar el código nativo de una biblioteca no es tan difícil.
Debes estar pensando "Oh, wow, esto es demasiada información", ¡solo dame el flujo de trabajo y listo!". Estás de suerte: el nativescript-dev-debugging
complemento de desarrollo es relativamente fácil de usar una vez que entiendes lo que hace.
Primero, deberá instalar ( npm install nativescript-dev-debugging
) y configurar el paquete para que todos sus scripts internos de compilación/ver puedan hacer su trabajo en su código fuente. Después de instalar el paquete, simplemente siga los pasos de configuración interactivos que le pedirán las ubicaciones de todas las "partes" que se utilizarán para construir todo el código fuente que desea depurar/desarrollar.
Aquí está la configuración que se generará después de instalar el paquete:
{
"pluginSrcFolder": "/Users/USER/plugin_repo/src",
"pluginPlatformFolder": "/Users/USER/plugin_repo/src/platforms",
"pluginIosSrcFolder": "/Users/USER/plugin_repo/src-native/ios",
"iosLibraryName": "LibraryName",
"pluginAndroidSrcFolder": "/Users/USER/plugin_repo/src-native/android",
"androidLibraryName": "LibraryName",
"demoFolder": "/Users/USER/plugin_repo/demo",
"demoAngularFolder": "/Users/USER/plugin_repo/demo-angular",
"demoVueFolder": "/Users/USER/plugin_repo/demo-vue",
"provisioningProfile": ""
}
Este es el contenido de un archivo llamado .debug.config.json
que contiene todas las configuraciones después de la configuración inicial del complemento. Esto se puede usar para habilitar la prueba de CI de su complemento NS, pero más sobre esto más adelante.
Una vez que haya instalado el paquete, notará que su complemento package.json
tiene algunos comandos nuevos de secuencias de comandos npm. Aquí es donde vive toda la magia del nativescript-dev-debugging
paquete. No se preocupe por actualizar esos comandos ahora o en el futuro, se mantendrán automáticamente cuando actualicemos el complemento con correcciones y nuevas funciones. Puede ver estos comandos como los bits en el flujo de trabajo que mantiene el complemento para que no tenga que preocuparse por cómo construir su biblioteca nativa.
Así es como se ve la ejecución del nd.run
comando principal:
Una vez que haya instalado y configurado correctamente el paquete, el comando principal del script npm que utilizará es nd.run
. Este comando proporciona toda la funcionalidad de forma interactiva para que pueda elegir fácilmente qué flujo de trabajo desea iniciar para un momento específico de su trabajo. Estos son los flujos de trabajo actuales que se proporcionan, dos para iOS y dos para Android :
No se preocupe por recordar todos los comandos específicos, hay una mejor forma más "interactiva" de activar el flujo de trabajo correcto, más detalles más adelante.
Veamos cómo nativescript-dev-debugging
se puede usar el complemento en un caso de uso real. En mi ejemplo, he decidido usar el tns-core-modules
paquete, que es desarrollado y mantenido por el equipo de NativeScript y por nuestra comunidad. Antes de comenzar, establezcamos una meta imaginaria y qué desafíos tenemos:
Nuestro objetivo: investigar un problema que creemos que se encuentra en el código nativo de iOS y Android de los módulos tns-core.
Los desafios:
Comencemos por preparar la versión local del tns-core-modules
código tns-core-modules-widgets
fuente y nuestra aplicación de prueba. Tenga en cuenta que esto no es un requisito del nativescript-dev-debugging
complemento, y puede evitarse si ya ha preparado su aplicación de prueba mediante el uso de un enlace simbólico del código fuente de su complemento como sugiere la semilla del complemento NS:
tns-core-modules
y del tns-core-modules-widgets
. puedes hacerlo desde aquí y aquí . Asegúrese de descargar ambos en el mismo directorio de su escritorio en un directorio llamado ns-dev-debugging para que los siguientes comandos funcionen mejor. Ambos repositorios proporcionan un "Flujo de trabajo del desarrollador" y se recomienda, pero no es obligatorio, leerlos antes de continuar.tns-core-modules
directorio, ábralo en una terminal y ejecute el compilador de TypeScript. Desde la raíz del repositorio de NativeScript ejecute:cd NativeScript/tns-core-modules/ && tsc
apps
directorio y npm instale los tns-core-modules locales previamente compilados:cd ../apps/ && npm i ../tns-core-modules/
tns-core-modules-widgets
repositorio y ejecute su build.sh
script. Esto creará todos los activos necesarios y creará un directorio dist que contiene una copia local del complemento:cd ../../tns-core-modules-widgets && bash build.sh
tns-core-modules
origen (el directorio de aplicaciones en tns-core-modules) y vuelva a instalar npm en la compilación anterior tns-core-modules-widgets:cd ../NativeScript/tns-core-modules/ && npm i ../../tns-core-modules-widgets/dist/package
Ahora que todo el código fuente local está preparado y nuestra aplicación de prueba está configurada, todo lo que tenemos que hacer es instalar y configurar el nativescript-dev-debugging
complemento:
Vaya al tns-core-modules
directorio (este es el complemento que vamos a depurar) y cree un n.debug.config.json
archivo con los siguientes contenidos (de forma predeterminada, este archivo se generará automáticamente durante la configuración inicial del complemento, pero para este ejemplo vamos a usar el pre- opción de configuración definida):
{
"pluginSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/tns-core-modules",
"pluginPlatformFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/dist/package/platforms",
"pluginIosSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/ios/TNSWidgets",
"iosLibraryName": "TNSWidgets",
"pluginAndroidSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/android",
"androidLibraryName": "widgets",
"demoFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"demoAngularFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"demoVueFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"provisioningProfile": ""
}
Tenga en cuenta que debe cambiar las rutas de directorio anteriores a las rutas reales de su entorno (cambie el
UserNamePlaceHolder
)
A continuación, instale el nativescript-dev-debugging
complemento:
npm i nativescript-dev-debugging --save-dev
¡Y eso es! Estás listo. El complemento de desarrollo debería haberse instalado usando el n.debug.config.json
archivo local, y ahora debería ver todos los nd.*
comandos de script npm en el package.json
archivo tns-core-modules.
Veamos qué comandos están disponibles ejecutando $ npm run nd.help
y eligiendo main
. Esto enumerará un par de comandos de script que activarán un flujo de trabajo para la situación específica en la que desee trabajar. Por ejemplo $ npm run nd.demo.ios
, se puede usar cuando simplemente desea ver el código nativo de su complemento, pero no espera realizar cambios. lo. De lo contrario, se recomienda usar el $ npm run nd.run
comando " porque proporciona un flujo de trabajo guiado para elegir escenarios más fácilmente y la capacidad de activar "observadores de archivos" para reconstruir su código fuente nativo.
Para obtener una mejor idea de lo que conducirá el ejemplo anterior, puede ver este video aquí que muestra el resultado cuando se ejecuta para iOS y para Android en estos videos:
Usando "nativescript-dev-debugging" con iOS
Usando "nativescript-dev-debugging" con Android
¡Una manera más fácil!
¡ Pero hay una manera aún más fácil de usar los nativescript-dev-debugging
comandos sin recordar los comandos de script largos anteriores! Simplemente puede recordar el comando más corto npm run nd.run
que lo guiará con indicaciones sobre el flujo de trabajo que desea iniciar.
Después de ejecutar cualquiera de los comandos que ejecutarán su "aplicación de prueba", Xcode o Android Studio se abrirán automáticamente con el código fuente nativo de su complemento. Para iniciar su sesión de depuración, deberá adjuntar al proceso de su aplicación de prueba.
Para iOS , después de abrir Xcode, simplemente vaya al menú Depurar > Adjuntar al proceso , busque la ID de su aplicación de prueba (para encontrar la ID, busque la etiqueta "id" en la package.json
aplicación NativeScript) y selecciónela:
Para Android , después de abrir Android Studio, haga clic en el ícono Adjuntar depurador al proceso de Android ubicado a la derecha de los menús de la barra de pestañas superior. Asegúrese de habilitar la casilla de verificación Mostrar todos los procesos para que se muestre el proceso de su aplicación:
Si has llegado hasta aquí, ¡gracias por leer esta entrada de blog ampliada! Espero que lo encuentre útil y que lo ayude con todos los geniales complementos de NativeScript que está desarrollando (y que desarrollará en el futuro).
Fuente: https://blog.nativescript.org/a-guide-to-debugging-your-nativescript-plugins/
1649276700
「 NativeScriptアプリとプラグインの完全なソースをどの程度開発できるのか」と疑問に思ったことはありませんか。NativeScriptフレームワークが完全なネイティブプラットフォーム(iOS / Android)APIアクセスを提供することをすでにご存知でしょう。それはすべて問題ありませんが、「コーナーケース」のバグのデバッグが必要になり、内部を調べてネイティブのObjective-C /を掘り下げる必要がある、避けられない将来の状況にとって、それはどういう意味ですか。プラグインコードのJavaコード?この質問への答えは、「はい、できます!」と響き渡ります。。しかし、次の質問「どうやって?」はどうですか?
これは私が答えようとする質問です-そしてプラグインのコードのネイティブソースコードをデバッグするためのまったく新しいアプローチを紹介します。
今日はnativescript-dev-debugging
、ダウンロードできるnpmパッケージを紹介します。
npm i nativescript-dev-debugging --save-dev
このパッケージは、アプリのUI、動作、またはコードのコンパイル/バンドルを提供しないという点で、他のNativeScriptnpmパッケージとは異なります。しかし、それはワークフローとして最もよく説明される何かを提供します。わかりました、「ワークフローとは何ですか?」と尋ねることができます。
ワークフローは、リソースを体系的に編成して、資料を変換したり、サービスを提供したり、情報を処理したりするプロセスによって可能になる、組織化された反復可能なビジネスアクティビティのパターンで構成されます。(ウィキペディア)
これは、特にNativeScriptプラグインをデバッグするnativescript-dev-debugging
タスクのために提供されるものです。そのコア機能では、パッケージは基本的に次の5つのステップを実行します。
.aar
ファイルとファイルを消費し.framework
ていて、それらのソースコード(別のネイティブiOSおよびAndroidチームが作成したもの)があるとします。上記のシーケンスの最終製品は、NativeScriptプラグインでの作業中に開発エクスペリエンスを向上させるために使用できる「ワークフロー」です。このようなプラグインの簡単な例は、tns-core-modules
プラグインを使用するプラグインです。プラグインは、ビルド済みのファイルtns-core-modules-widgets
を保持するだけです。.aar.framework
さて、これまでに成功した場合は、「わかりました。「もの」を再構築する必要がありますが、「ワークフロー」はどうですか?」と自問する必要があります。さて、これはどのように-そしてなぜそのようなパッケージのアイデアnativescript-dev-debugging
が作成されたのかを説明するのに最適な時期です。
NativeScriptチームの内部では、99%の人がプラグインで使用されているライブラリのネイティブコードを変更し(NativeScriptではすべてがプラグインであることを忘れないでください)、そのコードを手動で再構築し、製品を手動で移動します。そのビルドをプラグインプラットフォームディレクトリに追加し、新しい機能または修正された機能をテストするために使用されるNSアプリケーションのビルドを手動でトリガーします。ご覧のとおり、このワークフローには「手動」がたくさんあるので、「これを「手動」で自動化して、NativeScriptチーム全体がフレームワークで日常業務を行うときに同じアプローチを使用できるとしたらどうなるか」というアイデアがありました。 」。これは、すべてのチームがより生産的になり、誰もが物事がどのように行われるかのステップを知っているので、より簡単なコラボレーションを可能にすることを意味します。
当然のことながら、このワークフローの統合と自動化について何かを行うことを決定した後、すぐにこの出力をNativeScriptコミュニティ全体で利用できるようにすることを決定しました。これにより、このようなタスクに直面するすべての人が作業をより速く簡単に行えるようになり、さらにはライブラリのネイティブコードを変更することはそれほど難しくありません。
「これは情報が多すぎる」と考えている必要があります。ワークフローを教えてください。それで完了です。運が良ければ、nativescript-dev-debugging
開発プラグインは、その機能を理解すれば比較的簡単に使用できます。
npm install nativescript-dev-debugging
まず、パッケージをインストール()して構成し、すべての内部ビルド/ウォッチスクリプトがソースコードで機能するようにする必要があります。パッケージをインストールした後、デバッグ/開発するすべてのソースコードをビルドするために使用されるすべての「パーツ」の場所を尋ねる対話型の構成手順に従うだけです。
パッケージのインストール後に生成される構成は次のとおりです。
{
"pluginSrcFolder": "/Users/USER/plugin_repo/src",
"pluginPlatformFolder": "/Users/USER/plugin_repo/src/platforms",
"pluginIosSrcFolder": "/Users/USER/plugin_repo/src-native/ios",
"iosLibraryName": "LibraryName",
"pluginAndroidSrcFolder": "/Users/USER/plugin_repo/src-native/android",
"androidLibraryName": "LibraryName",
"demoFolder": "/Users/USER/plugin_repo/demo",
"demoAngularFolder": "/Users/USER/plugin_repo/demo-angular",
"demoVueFolder": "/Users/USER/plugin_repo/demo-vue",
"provisioningProfile": ""
}
.debug.config.json
これは、プラグインの初期設定後のすべての構成を保持するという名前のファイルの内容です。これは、NSプラグインのCIテストを有効にするために使用できますが、これについては後で詳しく説明します。
パッケージをインストールした後、プラグインpackage.json
にいくつかの新しいnpmスクリプトコマンドがあることに気付くでしょう。nativescript-dev-debugging
これは、パッケージのすべての魔法が生きている場所です。現在または将来、これらのコマンドを更新する必要はありません。プラグインを修正および新機能で更新すると、コマンドは自動的に維持されます。これらのコマンドは、プラグインによって維持されるワークフローの一部と見なすことができるため、ネイティブライブラリの構築方法について心配する必要はありません。
メインnd.run
コマンドの実行は次のようになります。
パッケージを正常にインストールして構成した後、使用するメインのnpmスクリプトコマンドはですnd.run
。このコマンドは、インタラクティブな方法ですべての機能を提供するため、作業の特定の瞬間に開始するワークフローを簡単に選択できます。提供されている現在のワークフローは次のとおりです。iOS用に2つ、Android用に2つです。
特定のコマンドをすべて覚えておく必要はありません。適切なワークフローをトリガーできる、より「インタラクティブな」方法があります。詳細については後で説明します。
nativescript-dev-debugging
プラグインを実際のユースケースでどのように使用できるかを見てみましょう。私の例tns-core-modules
では、NativeScriptチームとコミュニティによって開発および保守されているパッケージを使用することにしました。始める前に、架空の目標と私たちが抱えている課題を設定しましょう。
私たちの目標: tns-core-modulesのネイティブiOSおよびAndroidコードにあると思われる問題を調査します。
課題:
まず、ローカルバージョンtns-core-modules
、tns-core-modules-widgets
ソースコード、およびテストアプリケーションを準備します。これはプラグインの要件ではないことに注意してnativescript-dev-debugging
ください。NSプラグインシードが示唆するように、プラグインのソースコードのシンボリックリンクを使用してテストアプリをすでに準備している場合は回避できます。
tns-core-modules
とのそれぞれのリポジトリをダウンロードする必要がありますtns-core-modules-widgets
。こことここからそうすることができます。以下のコマンドが最適に機能するように、両方をデスクトップのns-dev-debuggingというディレクトリの同じディレクトリにダウンロードしてください。どちらのリポジトリも「開発者ワークフロー」を提供します。続行する前にそれらを読むことをお勧めしますが、必須ではありません。tns-core-modules
ディレクトリに移動し、ターミナルで開いてTypeScriptコンパイラを実行します。NativeScriptリポジトリのルートから次のコマンドを実行します。cd NativeScript/tns-core-modules/ && tsc
apps
npmは以前にコンパイルされたローカルtns-core-modulesをインストールします。cd ../apps/ && npm i ../tns-core-modules/
tns-core-modules-widgets
リポジトリのルートに移動し、そのbuild.sh
スクリプトを実行します。これにより、必要なすべてのアセットが作成され、プラグインのローカルコピーを含むdistディレクトリが作成されます。cd ../../tns-core-modules-widgets && bash build.sh
tns-core-modules
ソースディレクトリ(tns-core-modulesのappsディレクトリ)に戻り、npmで以前にビルドしたtns-core-modules-widgetsを再度インストールします。cd ../NativeScript/tns-core-modules/ && npm i ../../tns-core-modules-widgets/dist/package
すべてのローカルソースコードが準備され、テストアプリがセットアップされたので、nativescript-dev-debugging
プラグインをインストールして構成するだけです。
tns-core-modules
ディレクトリ(これはデバッグするプラグインです)に移動n.debug.config.json
し、次の内容のファイルを作成します(デフォルトでは、このファイルはプラグインの初期構成時に自動生成されますが、この例では、事前設定を使用します。定義された構成オプション):
{
"pluginSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/tns-core-modules",
"pluginPlatformFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/dist/package/platforms",
"pluginIosSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/ios/TNSWidgets",
"iosLibraryName": "TNSWidgets",
"pluginAndroidSrcFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/tns-core-modules-widgets/android",
"androidLibraryName": "widgets",
"demoFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"demoAngularFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"demoVueFolder": "/Users/‘UserNamePlaceHolder’/Desktop/ns-dev-debugging/NativeScript/apps",
"provisioningProfile": ""
}
上記のディレクトリパスを環境からの実際のパスに変更する必要があることに注意してください(を変更してください
UserNamePlaceHolder
)
次に、nativescript-dev-debugging
プラグインをインストールします。
npm i nativescript-dev-debugging --save-dev
以上です!完了です。devプラグインはローカルファイルを使用してインストールされているはずです。これで、tns-core-modulesファイルにn.debug.config.json
すべてのnpmスクリプトコマンドが表示されます。nd.*package.json
$ npm run nd.help
を実行して選択することにより、どのコマンドを使用できるかを見てみましょうmain
。これにより、作業したい特定の状況のワークフローをトリガーするいくつかのスクリプトコマンドが一覧表示されます。たとえば$ npm run nd.demo.ios
、プラグインのネイティブコードを表示したいが、変更を加える予定がない場合に使用できます。それに。それ以外の場合は、「コマンド」を使用することをお勧めします。$ npm run nd.run
これは、シナリオを簡単に選択できるガイド付きワークフローと、「ファイルウォッチャー」をトリガーしてネイティブソースコードを再構築する機能を提供するためです。
上記の例が何につながるかをよりよく理解するために、これらのビデオでiOSおよびAndroidで実行した場合の結果を示すこのビデオをここで見ることができます。
iOSで「nativescript-dev-debugging」を使用する
Androidで「nativescript-dev-debugging」を使用する
より簡単な方法!
nativescript-dev-debugging
しかし、上記の長いスクリプトコマンドを覚えていなくても、コマンドを使用する簡単な方法があります。npm run nd.run
開始するワークフローに関するプロンプトを表示する最短のコマンドを覚えておくだけです。
「テストアプリ」を実行するコマンドのいずれかを実行すると、プラグインのネイティブソースコードを使用してXcodeまたはAndroidStudioが自動的に開きます。デバッグセッションを開始するには、テストアプリのプロセスにアタッチする必要があります。
iOSの場合、Xcodeを開いた後、[デバッグ]> [プロセスにアタッチ]メニューに移動し、テストアプリのIDを見つけて(IDを見つけるにpackage.json
は、NativeScriptアプリの「id」タグを探します)、次のように選択します。
Androidの場合、Android Studioを開いた後、上部のタブストリップメニューの右側にある[デバッガーをAndroidプロセスにアタッチ]アイコンをクリックします。アプリのプロセスが表示されるように、必ず[すべてのプロセスを表示]チェックボックスをオンにしてください。
ここまで進んだら、この拡張ブログ投稿を読んでいただきありがとうございます!これがお役に立てば幸いです。また、開発中の(そして将来開発される予定の)すべてのクールなNativeScriptプラグインに役立つことを願っています。
ソース:https ://blog.nativescript.org/a-guide-to-debugging-your-nativescript-plugins/
1647252792
This video will give you 11 of my favorite most profitable app ideas that have been proven to work and make over $10K per month in revenue. These are not just any old apps - these make money! And I'll even show you how to get started with them right away so that you can start making money ASAP!
#businesses #webdev #web-development #startup #mobile-apps #nativescript #ionic #reactnative #ios #android
1646996624
https://www.blog.duomly.com/sign-in-with-apple-guide/
Apple has announced a new sign-in feature called “Sign In with Apple.” This new feature will allow users to sign in to apps and websites using their Apple ID rather than creating a separate username and password.
Here’s what you need to know about how Sign In with Apple will work for app owners.
#ios #mobile #mobile-apps #flutter #ionic #cordova #xamarin #nativescript #startup #startups
1644803702
This is a condensed version of what I did on stream to create a go vs typescript server and the learnings I had from it.
github.com/ThePrimeagen/tyrone-biggums
VimRC & i3: https://github.com/ThePrimeagen/.dotfiles