xccjk / x-blog

学习笔记
17 stars 2 forks source link

react native #90

Open xccjk opened 1 year ago

xccjk commented 1 year ago

报错 Invalid Podfile file: [!] Specifying multiple post_install hooks is unsupported..

post_install do |installer|
    flipper_post_install(installer)
  end
end

post_install do |pi|
  pi.pods_project.targets.each do |t|
    t.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
    end
  end
end

修改后

post_install do |pi|
  flipper_post_install(installer)
  pi.pods_project.targets.each do |t|
    t.build_configurations.each do |config|
      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '9.0'
    end
  end
end
xccjk commented 1 year ago

报错 Error installing Flipper

image

网络原因导致的报错

issue

xccjk commented 1 year ago

react native ui框架

https://github.com/rilyu/teaset

xccjk commented 11 months ago

react-native 代码修改未生效

使用react-native时,经常会出现调试模式下,修改js代码,然后依然运行旧代码的问题。这个时候禁用调试窗口的cache即可。

具体就在NetWork里,勾选Disable cache。

2021060915193550

xccjk commented 11 months ago

react native onLongPress方法在模拟器上失效

在启用了React Native Debugger的真实设备上进行测试后,这种情况会随机发生。禁用React Native Debugger将使您的问题消失

xccjk commented 10 months ago

react native setInterval 在真机模拟器上执行不正确

在启用了React Native Debugger的真实设备上进行测试后,setInterval执行不正确。禁用React Native Debugger将使您的问题消失

xccjk commented 3 months ago

react native中集成阿里云推送

安装依赖

pnpm install aliyun-react-native-push

Android配置

android/app/src/main/AndroidManifest.xml

<!-- 阿里云推送 -->
<meta-data
    android:name="com.alibaba.app.appkey"
    android:value="${ALIPUSH_APPKEY}" />
<meta-data
    android:name="com.alibaba.app.appsecret"
    android:value="${ALIPUSH_APPSECRET}" />

<receiver android:name="com.aliyun.ams.push.AliyunPushMessageReceiver" android:exported="false">
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
    </intent-filter>
    <intent-filter>
        <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
    </intent-filter>
</receiver>

android/settings.gradle

include ':aliyun-react-native-push'
project(':aliyun-react-native-push').projectDir = new File(rootProject.projectDir, '.../node_modules/aliyun-react-native-push/android')

android/settings.gradle

// 配置HMS Core SDK的Maven仓地址。
maven {
  url 'https://developer.huawei.com/repo/'
}

android/app/build.gradle

defaultConfig {
    ...
    manifestPlaceholders = [
        ...
        ALIPUSH_APPKEY    : "xxx",
        ALIPUSH_APPSECRET : "xxx",
    ]
   ...
}

iOS配置

#import <CloudPushSDK/CloudPushSDK.h>
#import <AliyunReactNativePush.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  ...

  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

  // 设置代理,必须写代理,不然无法监听通知的接收与点击事件
  center.delegate = self;

  // 判断是否已申请通知权限
  [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
      if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined ||
          settings.authorizationStatus == UNAuthorizationStatusDenied) {
          // 申请通知权限
          [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge |
                                                   UNAuthorizationOptionSound |
                                                   UNAuthorizationOptionAlert )
                                completionHandler:^(BOOL granted, NSError * _Nullable error) {
              if (!error && granted) {
                  // 用户点击允许
                  NSLog(@"注册成功");
              } else {
                  // 用户点击不允许
                  NSLog(@"注册失败");
              }
          }];
      }
  }];

  // 判断是否已注册远程推送
  if (application.isRegisteredForRemoteNotifications == NO) {
      // 注册远程推送,获取 device token
      [application registerForRemoteNotifications];
  }

  ...

  return YES;
}

//注册 APNS 成功并上报 DeviceToken
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

  NSString *tokenStr = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
                         stringByReplacingOccurrencesOfString: @">" withString: @""]
                        stringByReplacingOccurrencesOfString: @" " withString: @""];
  self.device_token = tokenStr;
  [AliyunPush didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

/*
 * APNs注册失败回调
 */
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  [AliyunPush didFailToRegisterForRemoteNotificationsWithError:error];
}

#pragma mark Notification Open
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo {
  [AliyunPush didReceiveRemoteNotification:userInfo];
}
//iOS 7 APNS
- (void)application:(UIApplication *)application didReceiveRemoteNotification:  (NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
  // iOS 10 以下 Required
  NSLog(@"iOS 7 APNS");
  [AliyunPush didReceiveRemoteNotifiaction:userInfo fetchCompletionHandler:completionHandler];
  completionHandler(UIBackgroundFetchResultNewData);
}

//ios 4 本地通知 todo
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
  NSDictionary *userInfo =  notification.userInfo;
  NSLog(@"iOS 4 本地通知");
  //  [[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_EVENT object:userInfo];
}

- (void)handleiOS10Notification:(UNNotification *)notification {
    UNNotificationRequest *request = notification.request;
    UNNotificationContent *content = request.content;
    NSDictionary *userInfo = content.userInfo;
    // 通知时间
    NSDate *noticeDate = notification.date;
    // 标题
    NSString *title = content.title;
    // 副标题
    NSString *subtitle = content.subtitle;
    // 内容
    NSString *body = content.body;
    // 角标
    int badge = [content.badge intValue];
    // 取得通知自定义字段内容,例:获取key为"Extras"的内容
    NSString *extras = [userInfo valueForKey:@"Extras"];
    // 通知打开回执上报
    [CloudPushSDK handleReceiveRemoteNotification:userInfo];
    NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d, extras: %@.", noticeDate, title, subtitle, body, badge, extras);
}

//iOS 10 前台收到消息
- (void)userNotificationCenter:(UNUserNotificationCenter *)center  willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
  NSDictionary * userInfo = notification.request.content.userInfo;
  if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    // Apns
    NSLog(@"iOS 10 APNS 前台收到消息");

    // 处理iOS 10通知相关字段信息
    [self handleiOS10Notification:notification];
    [AliyunPush userNotificationCenter:center willPresentNotification:notification withCompletionHandler:completionHandler];
    completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionSound);
  }
  else {
    // 本地通知 todo
    NSLog(@"iOS 10 本地通知 前台收到消息");
    //    [[NSNotificationCenter defaultCenter] postNotificationName:J_LOCAL_NOTIFICATION_EVENT object:userInfo];
  }
  //需要执行这个方法,选择是否提醒用户,有 Badge、Sound、Alert 三种类型可以选择设置
  completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionSound);
}

//iOS 10 消息事件回调
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler: (void (^)(void))completionHandler {
  NSDictionary * userInfo = response.notification.request.content.userInfo;
  if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    NSLog(@"iOS 10 APNS 消息事件回调");
    [AliyunPush userNotificationCenter:center didReceiveNotificationResponse:response withCompletionHandler:completionHandler];
  }
  else {
    // 本地通知 todo
    NSLog(@"iOS 10 本地通知 消息事件回调");
  }
  // 系统要求执行这个方法
  completionHandler();
}
- (void)applicationDidBecomeActive:(UIApplication *)application{
  //重置个推角标
  if (application.applicationIconBadgeNumber > 0) {  //badge number 不为0,说明程序有个推图标
    //如果需要角标清空需要调用系统方法设置
    [application setApplicationIconBadgeNumber: 0];   //将图标清零。
  }
}

使用

alipush.ts

// 阿里云推送通知
import * as AliyunPush from 'aliyun-react-native-push';
import { Platform } from 'react-native';

import { isJson } from '../utils/math';

const IMPORTANCE_DEFAULT = 3;

const channel = [
  { id: 'xxx', name: 'xx', importance: IMPORTANCE_DEFAULT, desc: 'xxx' },
];

const CONFIG_ENV: any = {
  'dev': { appKey: 'xxx', appSecret: 'xxx' },
  'test': { appKey: 'xxx', appSecret: 'xxx' },
};

export class AliyunPushManager {
  /**
   * @description 单例对象
   */
  private static instance = new AliyunPushManager();
  // 禁止外部调用
  private constructor() {
    this.pushInitial();
  }
  /**
   * @description 获取alipush管理对象
   */
  static getInstance(): AliyunPushManager {
    return AliyunPushManager.instance;
  }

  pushInitial(): void {
    if (Platform.OS == 'ios') {
      // 系统静音不播放
    } else {
    }
  }

  // 接收自定义消息
  addReceiveCustomMsgListener(callback: (message: Object) => void): void {
    AliyunPush.addMessageCallback((message: any) => {
      console.log('自定义消息', message);
      if (message) {
        if (Platform.OS === 'android') {
          let { content } = message || {};
          let result = isJson(content) ? JSON.parse(content) : {};
          callback(result);
        } else {
          let { body } = message || {};
          let result = isJson(body) ? JSON.parse(body) : {};
          callback(result);
        }
      }
    });
  }

  // 移除自定义消息
  removeMsgListener(callback: (message: Object) => void): void {
    AliyunPush.addNotificationRemovedCallback(callback);
  }

  // 推送通知回调
  addNotificationListener(callback: any): void {
    AliyunPush.addNotificationRemovedCallback(callback);
    AliyunPush.addNotificationCallback(callback);
  }

  // 通知栏打开通知扩展处理
  addNotificationOpenedCallback(callback: any): void {
    AliyunPush.addNotificationRemovedCallback(callback);
    AliyunPush.addNotificationOpenedCallback(callback);
  }

  // 设置日志
  async setLog() {
    const enable = true;
    if (enable) {
      if (Platform.OS === 'ios') {
        await AliyunPush.turnOnIOSDebug();
        console.log('push-打开ios Debug日志成功');
      } else {
        await AliyunPush.setAndroidLogLevel(2);
        console.log('push-打开android Debug日志成功');
      }
    }
  }

  // 初始化
  async init(callback) {
    if (Platform.OS === 'ios') {
      const { appKey, appSecret } = CONFIG_ENV.dev || {};
      const { code, errorMsg } = await AliyunPush.initPush(appKey, appSecret);
      if (code === AliyunPush.kAliyunPushSuccessCode) {
        console.log('push-initPush: 初始化iOS AliyunPush成功');
        callback && callback();
      } else {
        console.log(`push-initPush: iOS AliyunPush 初始化失败,errorMsg: ${errorMsg?.toString()}`);
      }
    } else {
      const res = await AliyunPush.initPush();
      if (res.code === AliyunPush.kAliyunPushSuccessCode) {
        console.log('push-init: 初始化Android AliyunPush成功');
        callback && callback();
      } else {
        let errorMsg = res.errorMsg?.toString();
        console.log(`push-init: Android AliyunPush 初始化失败,errorMsg: ${errorMsg}`);
      };
    }
  }

  // 开始初始化
  loadJs(callback?: any) {
    AliyunPushManager.getInstance().setLog();
    AliyunPushManager.getInstance().init(callback);
    AliyunPushManager.getInstance().setChannel();
    if (Platform.OS === 'ios') {
      AliyunPushManager.getInstance().getApnsDeviceToken();
      AliyunPushManager.getInstance().isIOSChannelOpened();
    }
  }

  // 设置别名
  async setAlias(alias: [string]) {
    await AliyunPushManager.getInstance().removeAlias();
    let CryptoJS = require('crypto-js');
    let signStrs: any[] = [];
    alias.map(async (key: string) => {
      let signStr = CryptoJS.MD5(key).toString();
      signStrs.push(signStr);
      const { code, errorMsg } = await AliyunPush.addAlias(signStr);
      if (code === AliyunPush.kAliyunPushSuccessCode) {
        console.log('push-setAlias: 添加别名成功')
      } else {
        console.log(`push-setAlias: 添加别名失败, error: ${errorMsg?.toString()}`);
      };
    });
    console.log('push-alias', alias, signStrs);
  }

  // 查询别名
  async listAlias() {
    const res: any = await AliyunPush.listAlias();
    console.log('push-listAlias', res);
    const { code, aliasList } = res;
    if (code === AliyunPush.kAliyunPushSuccessCode) {
      return aliasList ? aliasList.split(',') : [];
    }
    return [];
  }

  // 删除别名
  async removeAlias(callback?: any) {
    const alias = await AliyunPushManager.getInstance().listAlias();
    if (alias.length) {
      const res = await Promise.all(alias.map((key: string) => {
        return AliyunPush.removeAlias(key);
      }));
      if (res.filter(item => item.code === AliyunPush.kAliyunPushSuccessCode).length === res.length) {
        console.log('push-removeAlias: 删除别名成功');
        callback && callback();
      } else {
        console.log(`push-removeAlias: 删除别名失败`);
      }
    }
  }

  // 获取设置ID
  async getDeviceId() {
    const deviceId = await AliyunPush.getDeviceId();
    if (deviceId === null) {
      console.log(`push-getDeviceId: deviceId为空,请先初始化AliyunPush`);
    } else {
      console.log(`push-getDeviceId: ${deviceId}`)
    }
  }

  // 设置渠道编号
  async createAndroidChannel(params: { id: string, name: string, importance: number, desc: string }) {
    if (Platform.OS === 'ios') {

    } else {
      const { code, errorMsg } = await AliyunPush.createAndroidChannel(params);
      if (code === AliyunPush.kAliyunPushSuccessCode) {
        console.log(`push-createAndroidChannel: 创建通道成功`);
      } else {
        console.log(`push-createAndroidChannel: 创建通道失败, error: ${errorMsg}`);
      }
    }
  }

  // 设置渠道list
  setChannel() {
    // 设置渠道编号
    channel.map(params => {
      AliyunPushManager.getInstance().createAndroidChannel(params);
    });
  }

  // ios 通知通道是否打开
  async isIOSChannelOpened() {
    const opened = await AliyunPush.isIOSChannelOpened();
    if (opened) {
      console.log('push-ios: 通道已打开');
    } else {
      console.log('push-ios: 通道未打开');
    }
  }

  // ios 获取APNs Token
  async getApnsDeviceToken() {
    const token = await AliyunPush.getApnsDeviceToken();
    console.log('push-token', token);
  }

  // 移除所有回调
  removePushCallback() {
    AliyunPush.removePushCallback()
  }
}
import { AliyunPushManager } from './alipush';

AliyunPushManager.getInstance().loadJs();
xccjk commented 1 week ago

fastlane 安装慢

不要使用下面这种方法安装,看不到进度,特别慢

sudo gem install -n /usr/local/bin fastlane -NV

解决方案:

ruby版本要求2.7+,通过rvm来安装多版本ruby版本

创建一个 Gemfile 文件,内容如下:

source "https://gems.ruby-china.com/"

gem "fastlane"

使用 Bundler 安装 Fastlane:

bundle install

验证 Fastlane 是否正确安装:

bundle exec fastlane --version
xccjk commented 1 week ago

rvm安装多版本ruby

查看当前版本:

ruby -v

查看可按照版本:

rvm list known

安装指定版本:

rvm install ruby-3.2.1

上面这样安装应该会报错,修改为下面命令:

rvm install ruby-3.2.1 --with-openssl-dir=`brew --prefix openssl`

设置默认版本:

rvm use 3.2.1 --default

参考