跳过这个facebook/react-native#1626 GitHub问题,我有一个关于在iOS共享扩展中设置React Native视图的问题
我发布了一个示例GitHub repo来演示这个问题,总结如下.
到目前为止,概念验证设置非常简单,但我觉得我缺少一些非常简单的东西.
在我react-native init搭建的Xcode项目我创建了一个新的共享扩展的目标,并在其连接相应的阵营原生静态库(libReact.a,libRCTWebSocket.a,等).这使我们的项目编译成一个非常简单的ShareViewController,这是一个简单的'ol' UIViewController.
从另一个应用程序激活我的共享扩展后,我ShareViewController被初始化但立即崩溃并显示以下日志消息:
2015-11-29 12:44:34.721 [warn][tid:com.facebook.React.JavaScript][RCTContextExecutor.m:129] 'undefined is not an object (evaluating \'RCTWebSocketModule.connect\')'
2015-11-29 12:44:34.726 ShareExtension[66473:2179009] -[RCTBatchedBridge redBox]: unrecognized selector sent to instance 0x7fb59d8ab200
2015-11-29 12:53:47.160 [warn][tid:com.facebook.React.JavaScript][RCTContextExecutor.m:129] 'Requiring module "InitializeJavaScriptAppEngine" which threw an exception'
2015-11-29 12:53:47.160 ShareExtension[66473:2179009] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[RCTBatchedBridge redBox]: unrecognized selector sent to instance …Run Code Online (Sandbox Code Playgroud) ios javascriptcore ios-frameworks react-native share-extension
我想在JavascriptCore上下文中定义一个函数,它接受可变数量的参数.
像这样的东西:
JSVirtualMachine* virtualMachine = [[JSVirtualMachine alloc] init];
JSContext* ctx = [[JSContext alloc] initWithVirtualMachine:virtualMachine];
ctx[@"func"] = ^(JSValue* value, ...){
va_list args;
va_start(args, value);
for (JSValue *arg = value; arg != nil; arg = va_arg(args, JSValue*)) {
NSLog( @"%@", arg);
}
va_end(args);
};
[ctx evaluateScript:@"func('arg1', 'arg2');"];
Run Code Online (Sandbox Code Playgroud)
我相信JSC包装器不会将第二个参数传递给块,因为va_list在记录第一个参数后迭代崩溃.
我也尝试过这个NSArray*惯例,它不起作用.
这有可能吗?
我想在JavaScriptCore上下文中实例化一个Swift类.
我尝试了与Playground不同的语法,也尝试过Xcode 6.4(Swift 1.2)和Xcode 7 beta 3(Swift 2.0),但没有成功= - (
也许我错过了什么.
在我在网上找到的更复杂的例子中,协议'create'函数被定义为'class func'但编译器拒绝这种语法告诉"类方法只允许在类中;使用'static'来声明静态方法"... 所以我做了.
这是我的代码(OS X 10.10.4 - Xcode 6.4).我用了一个游乐场:
//: Playground - noun: a place where people can play
import Foundation
import JavaScriptCore
let context = JSContext()
// errors handling
context.exceptionHandler = { context, exception in
println("JS Error: \(exception)")
}
@objc
protocol PersonJavaScritMethod : JSExport {
func sayHello()
static func create(name : String) -> Person
}
class Person : NSObject, PersonJavaScritMethod {
var name : String!
init(name:String) {
super.init() …Run Code Online (Sandbox Code Playgroud) 我想在 React Native 中创建一个 TCP 套接字,连接到端口为 23 的 telnet 服务器。
我发现有'RCTWebSocket',但它似乎只支持http、https、ws、wss协议,并且在远程响应时总是出现错误。
有没有一种方法可以使用 TCP 套接字,它不仅适用于 http、ws 协议?
我们有一个应用程序,主要是一个基于javascript的Web应用程序的UIWebView.我们遇到的要求是能够向用户播放音频然后记录用户,回放该记录以进行确认,然后将音频发送到服务器.这适用于Chrome,Android和其他平台,因为该功能内置于浏览器中.不需要本机代码.
遗憾的是,iOS(iOS 8/9)Web视图缺乏录制音频的能力.
我们尝试的第一个解决方法是使用AudioQueue录制音频并将数据(LinearPCM 16bit)传递给JS AudioNode,以便Web应用程序可以像处理其他平台一样处理iOS音频.这就达到了我们可以将音频传递给JS的程度,但应用程序最终会因内存访问错误而崩溃,或者javascript方面无法跟上发送的数据.
下一个想法是将录音保存到文件并将部分音频数据发送到JS以获得视觉反馈,这是在录制期间显示的基本音频可视化器.
线性PCM签名为16bit时,音频记录并播放到WAVE文件.JS可视化工具是我们陷入困境的地方.期待线性PCM无符号8位,所以我添加了一个可能错误的转换步骤.我尝试了几种不同的方式,主要是在网上找到的,但是在我们进入转换步骤之前,没有找到一种可以让我认为其他错误或缺失的方法.
由于我不知道问题究竟是什么或在哪里,我将转储下面的代码用于音频录制和播放类.欢迎任何建议解决或绕过某种方式解决此问题.
我的一个想法是使用不同的格式标记以不同的格式(CAF)进行记录.查看生成的值,非带符号的16位整数甚至接近最大值.我很少看到+/- 1000以上的任何东西.是因为AudioStreamPacketDescription中的kLinearPCMFormatFlagIsPacked标志?删除该标志会因为格式无效而导致音频文件无法创建.也许切换到CAF会起作用,但我们需要在将音频发送回服务器之前转换为WAVE.
或者我从签名的16位到无符号8位的转换是错误的?我也试过了比特换档和铸造.唯一的区别是,通过此转换,所有音频值都被压缩到125到130之间.位移和转换将其更改为0-5和250-255.这并没有真正解决JS方面的任何问题.
下一步是,不是将数据传递给JS,而是通过FFT函数运行它,并生成JS直接用于音频可视化器的值.在去那个方向之前,我宁愿弄清楚我是否做了一些明显错误的事情.
AQRecorder.h - 编辑:将更新的音频格式更新为LinearPCM 32bit Float.
#ifndef AQRecorder_h
#define AQRecorder_h
#import <AudioToolbox/AudioToolbox.h>
#define NUM_BUFFERS 3
#define AUDIO_DATA_TYPE_FORMAT float
#define JS_AUDIO_DATA_SIZE 32
@interface AQRecorder : NSObject {
AudioStreamBasicDescription mDataFormat;
AudioQueueRef mQueue;
AudioQueueBufferRef mBuffers[ NUM_BUFFERS ];
AudioFileID mAudioFile;
UInt32 bufferByteSize;
SInt64 mCurrentPacket;
bool mIsRunning;
}
- (void)setupAudioFormat;
- (void)startRecording;
- (void)stopRecording;
- (void)processSamplesForJS:(UInt32)audioDataBytesCapacity audioData:(void *)audioData;
- (Boolean)isRunning;
@end
#endif
Run Code Online (Sandbox Code Playgroud)
AQRecorder.m - 编辑:将更新的音频格式更新为LinearPCM 32bit Float.在processSamplesForJS中添加了FFT步骤,而不是直接发送音频数据.
#import <AVFoundation/AVFoundation.h>
#import "AQRecorder.h"
#import "JSMonitor.h" …Run Code Online (Sandbox Code Playgroud) 我使用JavaScriptCore框架在iOS中执行以下javascript代码.javascript代码是浏览器化的.
var myCallback = undefined;
*browserify logic*
{
1: [function(require, module, exports) {
var q = require('./user');
var p = new Promise(function(resolved, reject) {
myCallback = function() {
resolved('test');
}
});
p.then(function(x) {printFunc('test');}).catch(function(e){printFunc('test2');});
q();
}, {
"./user": 2
}],
2: [function(require, module, exports) {
function q() {
printFunc("Callback called!");
myCallback();
printFunc("Callback called end!");
}
module.exports = q;
}, {}]
}, {}, [1]);
Run Code Online (Sandbox Code Playgroud)
printFunc是一个在Swift中实现的方法,只是打印一些东西到控制台.这是实施:
let printFunction : @convention(block) (String) -> String = {input in
print("|\(input)|")
return ""
}
Run Code Online (Sandbox Code Playgroud)
问题是我收到以下错误:
|Callback …Run Code Online (Sandbox Code Playgroud) 我想在 JavascriptCore 中加载一个 javascript 模块(在 iOS 上)。
我正在通过 iOS 端的普通 HTTP 请求获取文件的文本。所以我可以将整个字符串解析为 JScontext。
但现在我想加载该模块,理想情况下,解决任何其他依赖项,尽管这不是必需的。
我已经尝试将 requireJS 用于 node,但它似乎有很多依赖项错误,而且可能有点过时了。
我也试过偷窃,但我不确定那是否是正确的道路。我也试过这个。https://github.com/millermedeiros/nodefy
本质上,我想在浏览器中执行 require js 的操作,但是在纯 javascript 环境中(没有浏览器,没有节点)。
我还想使用 browserify 将所有内容打包,并查看了这样的内容 - RequireJS 加载字符串
问题是,当我浏览代码时,(需要,requirejs)该过程因未找到的依赖关系而失败?
任何人都可以指出我正确的方向吗?
我在我的应用程序中使用了 a JSContext,它运行良好,但我有点担心内存使用情况。当我使用完上下文后,它仍然作为调试目标位于我的 Safari 开发菜单中,当我运行“调试内存图”时,许多 JavaScriptCore 对象都在徘徊。
这是预期的(即,它会根据需要在将来被回收),还是表明我正在发生内存泄漏?内存图没有显示任何内容,但一定有某些东西保存在这些 JavaScriptCore 对象上。
我正在尝试使用 JSCore 从 Swift 中的 javascript SDK 执行异步函数。我已经能够完成评估和查看脚本的内容,但在实际调用异步函数时并未成功。这是我的代码,用于验证我是否已阅读该脚本。关于如何实现这一目标有什么想法吗?
lazy var context: JSContext? = {
let context = JSContext()
guard let
commonJSPath = Bundle.main.path(forResource: "test", ofType: "js") else {
print("Unable to read resource files.")
return nil
}
do {
let common = try String(contentsOfFile: commonJSPath, encoding: String.Encoding.utf8)
_ = context?.evaluateScript(common)
} catch (let error) {
print("Error while processing script file: \(error)")
}
return context
}()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用JSContext. 它运行良好,但我无法捕捉到console.log()语句。我怎样才能获得这些函数调用的结果,以便我也可以在 Swift 中打印它们?
示例代码
let jsSource = "var testFunct = function(message) { console.log(\"kud\"); return \"Test Message: \" + message;}"
let context = JSContext()
context?.evaluateScript(jsSource)
let testFunction = context?.objectForKeyedSubscript("testFunct")
let result = testFunction?.call(withArguments: ["the message"])
print(result!)
Run Code Online (Sandbox Code Playgroud)
日志示例
测试消息:消息
javascriptcore ×10
ios ×5
javascript ×5
swift ×3
react-native ×2
amd ×1
core-audio ×1
ios7 ×1
iphone ×1
require ×1
requirejs ×1
uiwebview ×1
websocket ×1
xcode ×1