-
Notifications
You must be signed in to change notification settings - Fork 24.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What are the guidelines for exposing native APIs? #7
Comments
It's the best time to talk about the hard questions :) Bridging APIs one-to-one is not trivial in React native for three big reasons:
So, it's actually non trivial to map 1 to 1 native apis. So far, the process was to start with a use case that one of the app we are building needs to support. At this point, we look at all the possible ways to expose the API and try to find the best one. One really important point is that we start from a use case, and not take an existing API and just rush to expose it all. The stance that we've taken so far is to try to make them as web/React friendly as possible.
This is why we want to do this private phase for now. We have never open sourced a project with such a crazy large API surface. My 5min thoughts on this is that what's in this github repo is going to lag in the APIs that it supports, but we have great extensibility tools that other people can fill the gap for APIs that we don't support yet. |
Would it be possible to support some generic FFI-like interface for interacting with the raw imperative native APIs? I don't know that much about the target platforms, but something like that would reduce pressure for a "proper" react-native supported version of the API and allow userland to experiment with options before committing to a solution in core. This is roughly how normal React deals with support for DOM stuff not explicitly exposed, and works very well in terms of not constraining the user. |
@glenjamin: this is a good idea. So far we worked close with our few users so we've been able to build high quality custom apis for their use case, but that's unlikely to scale. Right now my thinking was to allow people to write their own bindings via plugins. So if a feature is not yet supported, they can bridge it themselves. But something automatic may be a useful escape hatch as well. The best way to know is to try it and see if it solves real use cases |
Closing as this is a discussion and not super actionable :) Feel free to keep talking here |
Wait for CityStore token for all action types
…crash on simulator, on device I got nothing but app freezed)! My app has an old version of JSONKit which is still using MRC. I think JSONKit is not needed if system version is available. Kicking out of JSONKit will make react native stronger. Crash stack: * thread facebook#11: tid = 0xbd672f, 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807, name = 'com.facebook.React.JavaScript', stop reason = EXC_BAD_ACCESS (code=EXC_I386_GPFLT) frame #0: 0x000000010a10edeb imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=22 key/value pairs) + 16971 at JSONKit.m:2807 frame facebook#1: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=2 key/value pairs) + 17351 at JSONKit.m:2811 frame facebook#2: 0x000000010a10ef67 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=25 key/value pairs) + 17351 at JSONKit.m:2811 frame facebook#3: 0x000000010a10e768 imobii-waiqin`jk_encode_add_atom_to_buffer(encodeState=0x00007f9b820a1000, objectPtr=@"3 elements") + 15304 at JSONKit.m:2778 * frame facebook#4: 0x000000010a10a26a imobii-waiqin`-[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=0x00007f9b831fbc80, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 2250 at JSONKit.m:2876 frame facebook#5: 0x000000010a109992 imobii-waiqin`+[JKSerializer serializeObject:options:encodeOption:block:delegate:selector:error:](self=JKSerializer, _cmd="serializeObject:options:encodeOption:block:delegate:selector:error:", object=@"3 elements", optionFlags=0, encodeOption=10, block=0x0000000000000000, delegate=0x0000000000000000, selector=<no value available>, error=domain: class name = NSInvocation - code: 0) + 178 at JSONKit.m:2831 frame facebook#6: 0x000000010a10f700 imobii-waiqin`-[NSArray(self=@"3 elements", _cmd="JSONStringWithOptions:error:", serializeOptions=0, error=domain: class name = NSInvocation - code: 0) JSONStringWithOptions:error:] + 112 at JSONKit.m:2985 frame facebook#7: 0x000000010ac13c02 imobii-waiqin`_RCTJSONStringifyNoRetry(jsonObject=@"3 elements", error=domain: class name = NSInvocation - code: 0) + 338 at RCTUtils.m:49 frame facebook#8: 0x000000010ac13990 imobii-waiqin`RCTJSONStringify(jsonObject=@"3 elements", error=0x0000000000000000) + 128 at RCTUtils.m:77 frame facebook#9: 0x000000010ab5fdfa imobii-waiqin`__27-[RCTContextExecutor setUp]_block_invoke_2(.block_descriptor=<unavailable>, moduleName=@"UIManager") + 218 at RCTContextExecutor.m:363 frame facebook#10: 0x00000001134495cc CoreFoundation`__invoking___ + 140 frame facebook#11: 0x000000011344941e CoreFoundation`-[NSInvocation invoke] + 286 frame facebook#12: 0x000000010db13db3 JavaScriptCore`JSC::ObjCCallbackFunctionImpl::call(JSContext*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 451 frame facebook#13: 0x000000010db13926 JavaScriptCore`JSC::objCCallbackFunctionCallAsFunction(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) + 262 frame facebook#14: 0x000000010db14bad JavaScriptCore`long long JSC::APICallbackFunction::call<JSC::ObjCCallbackFunction>(JSC::ExecState*) + 573 frame facebook#15: 0x000000010dade340 JavaScriptCore`JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 528 frame facebook#16: 0x000000010dae535d JavaScriptCore`llint_entry + 22900 frame facebook#17: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326 frame facebook#18: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169 frame facebook#19: 0x000000010d9985ad JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 493 frame facebook#20: 0x000000010d76cb7e JavaScriptCore`JSC::call(JSC::ExecState*, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 62 frame facebook#21: 0x000000010d929a55 JavaScriptCore`JSC::callGetter(JSC::ExecState*, JSC::JSValue, JSC::JSValue) + 149 frame facebook#22: 0x000000010dad49fb JavaScriptCore`llint_slow_path_get_by_id + 2203 frame facebook#23: 0x000000010dae22f0 JavaScriptCore`llint_entry + 10503 frame facebook#24: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#25: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804 frame facebook#26: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#27: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#28: 0x000000010dae52fd JavaScriptCore`llint_entry + 22804 frame facebook#29: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#30: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#31: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#32: 0x000000010dae552a JavaScriptCore`llint_entry + 23361 frame facebook#33: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#34: 0x000000010dae5368 JavaScriptCore`llint_entry + 22911 frame facebook#35: 0x000000010dadf7d9 JavaScriptCore`vmEntryToJavaScript + 326 frame facebook#36: 0x000000010d9b1959 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 169 frame facebook#37: 0x000000010d998264 JavaScriptCore`JSC::Interpreter::execute(JSC::ProgramExecutable*, JSC::ExecState*, JSC::JSObject*) + 10404 frame facebook#38: 0x000000010d7a8786 JavaScriptCore`JSC::evaluate(JSC::ExecState*, JSC::SourceCode const&, JSC::JSValue, WTF::NakedPtr<JSC::Exception>&) + 470 frame facebook#39: 0x000000010d9f6fb8 JavaScriptCore`JSEvaluateScript + 424 frame facebook#40: 0x000000010ab6379e imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke.264(.block_descriptor=<unavailable>) + 414 at RCTContextExecutor.m:589 frame facebook#41: 0x000000010ab63262 imobii-waiqin`__68-[RCTContextExecutor executeApplicationScript:sourceURL:onComplete:]_block_invoke(.block_descriptor=<unavailable>) + 498 at RCTContextExecutor.m:589 frame facebook#42: 0x000000010ab63df8 imobii-waiqin`-[RCTContextExecutor executeBlockOnJavaScriptQueue:](self=0x00007f9b832f6040, _cmd="executeBlockOnJavaScriptQueue:", block=0x00007f9b80c92970) + 248 at RCTContextExecutor.m:627 frame facebook#43: 0x000000010eb1d7a7 Foundation`__NSThreadPerformPerform + 283 frame facebook#44: 0x0000000113486301 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 frame facebook#45: 0x000000011347c22c CoreFoundation`__CFRunLoopDoSources0 + 556 frame facebook#46: 0x000000011347b6e3 CoreFoundation`__CFRunLoopRun + 867 frame facebook#47: 0x000000011347b0f8 CoreFoundation`CFRunLoopRunSpecific + 488 frame facebook#48: 0x000000010ab5e41b imobii-waiqin`+[RCTContextExecutor runRunLoopThread](self=RCTContextExecutor, _cmd="runRunLoopThread") + 363 at RCTContextExecutor.m:284 frame facebook#49: 0x000000010ebc012b Foundation`__NSThread__start__ + 1198 frame facebook#50: 0x00000001140869b1 libsystem_pthread.dylib`_pthread_body + 131 frame facebook#51: 0x000000011408692e libsystem_pthread.dylib`_pthread_start + 168 frame facebook#52: 0x0000000114084385 libsystem_pthread.dylib`thread_start + 13
…iew_refresh_control Synthesize scrollview refreshControl
This is not an issue per se, but something that #4 got me thinking about.
There are often many ways to expose the same native API. How opinionated does React Native want to be? For example, Xamarin mirrors all available iOS SDK but has a very specific and consistent API guidelines document that explains how native Cocoa APIs are mapped to be C#-friendly. This means that, if you know how certain API is called in Objective C, you can more or less infer what it will be in Xamarin's world without consulting the docs.
With React Native, this gets even more interesting because we may need both imperative platform-bridging API (like proposed
StatusBarIOS.setStyle
) as well as declarative React components sitting on top of such APIs, for exampleNavigatorIOS
.Are there any guidelines we want to establish for such components? Are we just trying to make the best declarative wrappers possible for every platform's native APIs? How fast are we willing to make breaking changes to them? (Unlike React, we have a lot of public API here.)
I'm sorry if this is premature talk but I'd love to get some sense of the direction of this project.
The text was updated successfully, but these errors were encountered: