First, I'm bridging Appcelerator with native iOS code and I don't have access to Hyperloop. The following functions exist in the native iOS code. They are compiled as an iOS module and called directly from the Appcelerator code:
MyAppModule.m
-(void)thisA
{
NSLog(#"***** Started A");
self.MyBridge = [MyAppProxy alloc];
[self.MyBridge callThis];
NSLog(#"***** Ended A");
}
-(void)thisB
{
NSLog(#"***** Started B");
self.MyBridge = [MyAppProxy alloc];
[self.MyBridge callThisOtherThing];
NSLog(#"***** Ended B");
}
-(void)thisC
{
NSLog(#"***** Started C");
self.MyBridge = [MyAppProxy alloc];
[self.MyBridge callThisOtherThing]; // Does the same thing B does
NSLog(#"***** Ended C");
}
MyAppProxy.m
-(void)callThis
{
thisVar = 1;
NSLog(#"***** thisVar set to 1");
}
-(void)callThisOtherThing
{
thisVar = 2;
NSLog(#"***** thisVar set to 2");
}
When I initially call thisA, it works. I see all 3 NSLogs and the expected result occurs. When I initially call thisB, it works. I see all 3 NSLogs and the expected result occurs.
When I call thisA again 5 minutes later, it still works. I see all 3 NSLogs and the expected result occurs. When I call thisB again 5 minutes later, it doesn't execute at all. I don't even see the first NSLog (Started B). If I then call thisC after that, it works just fine. Ugh.
There's ostensibly no difference between thisA and thisB. Yet, one fires multiple times and the other only fires once.
What am I doing wrong? I'm at wits end. Thanks guys.
Related
I am using a Bluno microcontroller to send / receive data from an iPhone, and everything is working as it should, but I would like to update the text of a UILabel with the real time data that is being printed from the Serial.print(numTicks); statement. If I stop the flowmeter the UILabel gets updated with the most current value, but I would like to update this label in realtime. I am not sure if this is a C / Arduino question or more of a iOS / Objective-C question. The sketch I'm loading on my Bluno looks like the following, https://github.com/ipatch/KegCop/blob/master/KegCop-Bluno-sketch.c
And the method in question inside that sketch looks like the following,
// flowmeter stuff
bool getFlow4() {
// call the countdown function for pouring beer
// Serial.println(flowmeterPin);
flowmeterPinState = digitalRead(flowmeterPin);
// Serial.println(flowmeterPinStatePinState);
volatile unsigned long currentMillis = millis();
// if the predefined interval has passed
if (millis() - lastmillis >= 250) { // Update every 1/4 second
// disconnect flow meter from interrupt
detachInterrupt(0); // Disable interrupt when calculating
// Serial.print("Ticks:");
Serial.print(numTicks);
// numTicks = 0; // Restart the counter.
lastmillis = millis(); // Update lastmillis
attachInterrupt(0, count, FALLING); // enable interrupt
}
if(numTicks >= 475 || valveClosed == 1) {
close_valve();
numTicks = 0; // Restart the counter.
valveClosed = 0;
return 0;
}
}
On the iOS / Objective-C side of things I'm doing the following,
- (void)didReceiveData:(NSData *)data Device:(DFBlunoDevice *)dev {
// setup label to update
_ticks = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[_tickAmount setText:[NSString stringWithFormat:#"Ticks:%#",_ticks]];
[_tickAmount setNeedsDisplay];
NSLog(#"ticks = %#",_ticks);
}
Basically I would like to update the value of the UILabel while the flowmeter is working.
UPDATE
I just tested the functionality again with the serial monitor within the Arduino IDE, and I got the same if not similar results as to what I got via Xcode and the NSLog statements. So this leads me to believe something in the sketch is preventing the label from updating in real time. :/ Sorry for the confusion.
So I'm not sure if this is an issue with Unity or with the Facebook Unity SDK, or something I might be doing? It only started appearing recently, it was working perfectly fine up until I had to update Unity for iOS9 font issues.
The point at which it crashes in Xcode is:
+ (instancetype)instanceWithRequestID:(int)requestID
{
FBUnitySDKDelegate *instance = [[FBUnitySDKDelegate alloc] init];
instance->_requestID = requestID;
[g_instances addObject:instance]; // Breaks on this line. instance is nil
return instance;
}
And the code I am using for the AppRequest is
public void RequestLivesFromFriends(string[] friendIds)
{
if(!FB.IsLoggedIn)
{
LoginToFacebook ();
return;
}
FB.AppRequest(
"Please send me a life!",
Facebook.Unity.OGActionType.ASKFOR,
livesIdValue,
friendIds,
"RequestLife",
"Request a life from your friends",
requestLifeCallback
);
}
Is there currently an issue with the SDK's? Or am I just doing something wrong?
Well, I found the solution myself in the end.
I had -fno-objc-arc set as the Compiler Flag on FBUnitySDKDelegate.m
Apparently, having that on with the more recent versions of the SDK (or maybe something else was causing it, I'm not exactly sure) causes the NSMutableArray g_instances to be converted to an NSString. So when the code tries to add the FBUnitySDKDelegate object 'instance' to g_instances, it is trying to call addObject on an NSString, passing in an FBUnitySDKDelegate, which obviously doesn't work.
So yeah, if you have this problem, check for Compiler Flags on the file.
I have a segmented control I wrote myself (UISegmenterControl) which sends a message once the selected segment has changed:
- (void)setSelectedSegmentIndex:(NSInteger)selectedSegmentIndex
{
if(_selectedSegmentIndex != selectedSegmentIndex) {
NSInteger segmentIndex = 0;
for (UISegmenterControlSegment *segmentButton in self.segmentButtons) {
if (segmentIndex == selectedSegmentIndex) {
[segmentButton setSelected:YES];
_selectedSegmentIndex = selectedSegmentIndex;
if (self.target != nil) {
if ([self.target respondsToSelector:self.action]) {
objc_msgSend(self.target, self.action, self);
}
}
}
else {
[segmentButton setSelected:NO];
}
segmentIndex++;
}
}
}
The objc_msgSend fires off (void)didChangeSegmentControl:(UISegmenterControl *)control in my view controller whilst passing a pointer to the segmented control itself.
Problem is, since upgrading to XCode 5.1 beta 4 and my development device to IOS 7.1 beta 4 my code is falling over on the device with EXC_BAD_ACCESS (code=1) when didChangeSegmentControl fires off.
It seems that the pointer to the segmented control (i.e. the 'control' parameter) is being lost between the objc_msgSend and didChangeSegmentControl.
What's confusing me most here is that this wasn't happening until I upgraded and still doesn't happen either on the simulator or on my device when profiling the app. I guess what I'm asking is: does this look to be a problem with my code (that somehow functioned perfectly fine on previous IOSes and/ or XCodes) or might this be an issue with the latest beta?
Please let me know if you need any more information about my app.
Rather than using objc_msgSend, can you use the following instead:
[self.target performSelectorOnMainThread:self.action withObject:self waitUntilDone:YES];
P.S. Thanks for the update on the correct objects in the comments
I want to make live streaming for more then two users on different devices and get api from opentok i had download demo app from ( https://github.com/opentok/OpenTok-iOS-Hello-World) and this is not webrtc, i had run application with key, session and token with disables of pear to pear,
And its working fine for two live streaming but while i tray to connect third stream i am not able to getting that,
I found staring in demo app that (On iPad 2 / 3 / 4, the limit is four streams. An app can have up to four simultaneous subscribers, or one publisher and up to three subscribers.)
with this i am testing with three iPads and got just two on screen
so how to make this more then two stream at a time in three iPads
The project you linked (OpenTok-iOS-Hello-World) is built to just subscribe to one stream. Just as a proof of concept, you can get two subscribers on screen pretty simply by just modifying a few methods and adding an instance variable in ViewController.m
Create a variable that tracks the number of subscribers:
#implementation ViewController {
OTSession* _session;
OTPublisher* _publisher;
OTSubscriber* _subscriber;
int _numSubscribers; // **NEW**
}
Initialize the variable in the initialization method:
- (void)viewDidLoad
{
[super viewDidLoad];
_session = [[OTSession alloc] initWithSessionId:kSessionId
delegate:self];
_numSubscribers = 0; // **NEW**
[self doConnect];
}
Make sure we aren't subscribing to our own stream:
static bool subscribeToSelf = NO;
Modify stop caring about whether there is already a subscriber in this session delegate method:
- (void)session:(OTSession*)mySession didReceiveStream:(OTStream*)stream
{
NSLog(#"session didReceiveStream (%#)", stream.streamId);
// See the declaration of subscribeToSelf above.
if ( (subscribeToSelf && [stream.connection.connectionId isEqualToString: _session.connection.connectionId])
||
(!subscribeToSelf && ![stream.connection.connectionId isEqualToString: _session.connection.connectionId])
) {
// ** Changing if statement **
if (_numSubscribers < 2) {
_subscriber = [[OTSubscriber alloc] initWithStream:stream delegate:self];
_numSubscribers++;
}
}
}
Place the subscribers next to one another, taking up a little less width:
- (void)subscriberDidConnectToStream:(OTSubscriber*)subscriber
{
NSLog(#"subscriberDidConnectToStream (%#)", subscriber.stream.connection.connectionId);
// ** Calculate the frame **
CGRect subFrame = CGRectMake(0, widgetHeight, widgetWidth / 2, widgetHeight)
if (_numSubscribers == 2) subFrame = CGRectOffset(subFrame, widgetWidth / 2, 0);
[subscriber.view setFrame:subFrame];
[self.view addSubview:subscriber.view];
}
NOTE: This solution doesn't result in a stable App. It should get you to a point where you can see both subscribers as long as you don't disconnect any of the iPads in between. To finish this off, you will need to store the OTSubscribers created in session:didRecieveStream: in a collection like NSArray, handle removing the right subscriber(s) and decrementing the _numSubscribers in session:didDropStream:, and thinking about how you want the updateSubscriber method to work instead.
If you look at the source code for hello world in the viewcontroller file line 93, you will see that it is only creating one subscriber. To have multiple subscribers simple create an array or hash object to store multiple subscribers.
I'm Trying to fire a custom event in phonegap on iOS. Ok what I've done so far :
I've created a custom plugin , I'm able to call my plugin from Javascript and all work properly. Basically the plugin show a ModalViewController presenting some native functionality
such as recording and editing a video, once the user has finished I will upload the video to youtube. I would like to fire an event when the download is completed but at the moment I wasn't able to do this.
This is part of the code I use :
In my index.html I have this function triggered by a click on a button, (I'm not a Javascript developer) nativeFunction basically call my custom plugin.
function testCustomPlugin()
{
MyClass.nativeFunction(
function(result) {
alert("Success : \r\n"+result);
},
function(error) {
alert("Error : \r\n"+error);
}
);
document.addEventListener("post_sent",onPostSent,false);
}
function onPostSent()
{
alert("post sent");
}
This is my MyClass.js :
var MyClass = {
nativeFunction: function(types, success, fail) {
return Cordova.exec(success, fail, "MyClass", "showInterface", types);
}
}
Inside MyClass.m I have two methods : showInterface and sendNotification,
showInterface.m
- (void) showInterface:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options
{
self.callbackID = [arguments objectAtIndex:0];
// missing code
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(sendSuccessNotification:)
name:#"PostSentNotification" object:nil];
}
-(void)sendSuccessNotification:(NSNotification *)notification
{
if (self.callbackID) {
NSLog(#"%#",callbackID);
NSLog(#"sendSuccessNotification");
NSDictionary *dictionary = [NSDictionary dictionaryWithObject:#"testCallBack"
forKey:#"returnValue"];
CDVPluginResult *result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsDictionary:dictionary
[result setKeepCallbackAsBool:YES];
[super writeJavascript:[result toSuccessCallbackString:self.callbackID]];
}
}
I can see in my log that sendSuccessNotification is called but the event is not fired, I am sure that I do something wrong in the javascript but the problem is that I don't know what.
Thanks in advance for any help
According to your code, I guess you are using PhoneGap / Cordova 1.5.0, right?
I'm asking because a lot of code has been changed in version 1.6.0.
In my opinion the following line is incorrect:
self.callbackID = [arguments objectAtIndex:0];
You can check this yourself by debugging the string value.
According to my information the following statement should be used to retrieve the correct callback id for your result object:
self.callbackID = [arguments pop];
Also, please make sure that you have registered your plugin in your Cordova.plist.
Hope this solves your issue.
Best,
Martin
your js does look a little weird - I recommend following this tutorial (or just download the project and take it from there;-)
http://www.adobe.com/devnet/html5/articles/extending-phonegap-with-native-plugins-for-ios.html