Stream screen with objective-c react-native - objective-c

I am building a module into my react native app to stream my screen and then send it to a server via a socket connection.
The java par works fine, I am using a method to get a capture of the screen and then send the base64 image to the server.
I do not really know about objective-c, I get a code to take screenshot but it seems some identifiers are not declared, reading the doc about objective-c and react-native I do not know what to import, seems to be automatic.
This is my actual code
#import "ScreenShare.h"
#implementation ScreenShare
// To export a module named ScreenShare
RCT_EXPORT_MODULE();
RCT_REMAP_METHOD(start,
startWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSDictionary *result = #{#"success": #true};
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
CGRect rect = [keyWindow bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[keyWindow.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
resolve(result);
}
RCT_REMAP_METHOD(stop,
stopWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSDictionary *result = #{#"success": #true};
resolve(result);
}
#end
My h file
#import <React/RCTBridgeModule.h>
#interface ScreenShare : NSObject <RCTBridgeModule>
#end
and for example, only on this line UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; I have:
Use of undeclared identifier 'keyWindow'
Use of undeclared identifier 'UIApplication'
Use of undeclared identifier 'UIWindow'

You should probably include at least
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
in either the .h or .m
If you're still having problems, I'd recommend you look at the structure of some other modules (e.g. RNFetchBlob) to get an idea of what's needed.

Related

Apple Metal without Interface Builder

I am racking my brain on this one. I've been trying to duplicate the initial metal project provided by Apple but without using interface builder at all. I'm able to create a window, but it's blank, nothing is rendering and I can't figure out why.
main.m
#import <Cocoa/Cocoa.h>
#import "AppDelegate.h"
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSApplication* app = [NSApplication sharedApplication];
AppDelegate* appDelegate = [[AppDelegate alloc] init];
[app setDelegate:appDelegate];
[app run];
}
return EXIT_SUCCESS;
}
AppDelegate.h
#import <Cocoa/Cocoa.h>
#interface AppDelegate : NSObject <NSApplicationDelegate> {
NSWindow *window;
}
#end
AppDelegate.m
#import <Metal/Metal.h>
#import "AppDelegate.h"
#import "GameViewController.h"
#interface AppDelegate ()
#end
#implementation AppDelegate
- (id)init {
if (self = [super init]) {
NSScreen* mainScreen = [NSScreen mainScreen];
NSRect frame = NSMakeRect(0, 0, mainScreen.frame.size.width / 2, mainScreen.frame.size.height / 2);
NSUInteger styleMask =
NSWindowStyleMaskTitled |
NSWindowStyleMaskResizable |
NSWindowStyleMaskClosable |
NSWindowStyleMaskMiniaturizable;
NSBackingStoreType backing = NSBackingStoreBuffered;
window = [[NSWindow alloc] initWithContentRect:frame styleMask:styleMask backing:backing defer:YES];
[window center];
GameViewController* gvc = [[GameViewController alloc] init];
MTKView* metalView = [[MTKView alloc] initWithFrame:frame device:MTLCreateSystemDefaultDevice()];
[metalView setClearColor:MTLClearColorMake(0, 0, 0, 1)];
[metalView setColorPixelFormat:MTLPixelFormatBGRA8Unorm];
[metalView setDepthStencilPixelFormat:MTLPixelFormatDepth32Float];
[metalView setDelegate:gvc];
[gvc setView:metalView];
[window setContentView:metalView];
//[window setContentViewController: gvc];
}
return self;
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification {
[window makeKeyAndOrderFront:self];
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
// Insert code here to initialize your application
}
- (void)applicationWillTerminate:(NSNotification *)aNotification {
// Insert code here to tear down your application
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender {
return YES;
}
#end
The other files; GameViewController.h, GameViewController.m, Shaders.metal, SharedStructures.h; are the same as what XCode 8.2.1 (8C1002) auto generates when you create a Game project that uses Metal with Objective-c.
You'll notice the line [window setContentViewController: gvc]; is commented out. When this is uncommented I get an EXEC_BAD_ACCESS on the first line of GameViewController.m's render function dispatch_semaphore_wait(_inflight_semaphore, DISPATCH_TIME_FOREVER);
Clearly there's something that I'm missing, but I've been googling all day and I can't seem to figure it out. Any help is much appreciated.
The issue is that, when an NSViewController such as the GameViewController is not loaded from a NIB, it doesn't call the -viewDidLoad method. The GameViewController does important work in that method.
You can move the creation of the view into an override of -loadView in GameViewController. Create the view and assign it to self.view. You don't need to set its delegate. The existing GameViewController code does that already. Setting the view's properties should be moved to -_setupView where the existing code already does that sort of thing.
Don't create the view in -[AppDelegate init]. Obviously, you also won't be able to set the view controller's view there, either. Just set the view controller as the window's content view controller (uncomment that line) and the rest will be taken care of automatically. When the window requests the content view controller's view property, it will call your override of -loadView along with the existing -viewDidLoad, etc.

trying to make a button spin in Xcode with 6.3.2 objective-C

I watched a video on how to make a button spin in Objective-C. I entered all the code exactly like in video except I got some syntex errors/ "!". I am very new to Xcode and only know some of the basics to javascript. Please help have been trying to figure this out for too long.
This is what I did in ViewController.h:
// ViewController.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#import <AVFoundation/AVFoundation.h>
This part in the code I get "!", it doesn't seem to like the "()". when I take that part out it's fine but the button doesn't seem to be recognized when it is called later on in ViewController.m. I'll explain what each "!" says to the write of the code where I'm getting each error. to separate it from the code ill put 2 "//" next to it.
#interface ViewController : UIViewController( // ! Method type specifier must start with '-' or '+'
I get 3 error messages on this next line of code.
IBOutlet UIButton *button; //! IBOutlet attribute ignored when parsing type, Expected selector for Objective-C method, and Expected ')'
) //! Expected identifier or '('
- (IBAction)spin:(id)sender;
#end
Now here's what I did in ViewController.m
// ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)spin:(id)sender {
CABasicAnimation *fullRotation = [CABasicAnimation
animationWithKeyPath:#"transform.rotate" ];
fullRotation.fromValue = [NSNumber numberWithFloat:0];
fullRotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
fullRotation.duration = 2.0;
fullRotation.repeatCount = 300;
in this part of the code I get the "!" again no matter what I do to change it
[button.layer addAnimation:fullRotation forKey:#"360"]; //! Use of undeclared identifier 'button'
}
#end
UIViewController( should not have the ( on the end.
just use:
// ViewController.h
#interface ViewController : UIViewController
#property(nonatomic, weak) UIButton *button;
- (IBAction)spin:(id)sender;
It's recommended to use #property since it generates getter/setter and you can set weak reference.
and in the implementation file add self.
[self.button.layer addAnimation:fullRotation forKey:#"360"]

Resizing a WebView instance

I'm just starting to learn OSX Cocoa app development. I would like to display a website inside a native OSX window. I thought a WebView would be the right way. I would like the webview to always take up 100% of the containing windows' size.
After struggling a bit, I understand how to catch the 'window resize' event, but I have no clue how to resize the web view according to the windows new size.
Here's what I have so far:
AppDelegate.h
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#interface AppDelegate : NSObject <NSApplicationDelegate, NSWindowDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (weak) IBOutlet WebView *websiteWebview;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
- (NSSize) windowWillResize:(NSWindow *)sender toSize:(NSSize)frameSize
{
WebView *view = [self websiteWebview];
[view setFrame:CGRectMake(0, 0, 1000, 1000)];
return frameSize;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[self window] setDelegate:self];
NSURL *url = [[NSURL alloc] initWithString:#"http://conradk.com"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[[[self websiteWebview] mainFrame] loadRequest:request];
}
#end
I thought calling [view setFrame:CGRectMake(0, 0, 1000, 1000)] would resize the web view as well, but it seems to not be the case.
Any tips / hints please? Is a WebView the right way to do this? Thanks for your help!
You need to make your WebView part of the window's contentView.
[self.window setContentView:self.websiteWebview];
By default, this will let the webView auto-resize with the window. You'll only need to mess with the sizing if you want the webview to do something other than match the size of the window.

Protocol Delegate doesn't get called

Hi Im trying to download a Photo from the internet using GCD. After the image is downloaded I call the delegate to let the class know that the image is downloaded.
Here is the code I use to download the image
-(void)getVenuePhotos:(NSString *)venueID
{
dispatch_queue_t getVenuePhotos = dispatch_queue_create ( "getVenuePhotos" , NULL );
dispatch_async (getVenuePhotos, ^{
//Download image, Lots of code not displaying
UIImage *image = [[UIImage alloc] initWithData:photoData];
dispatch_async(dispatch_get_main_queue(),^{
//This delegate doesn't get called
[self.delegate gotVenuePhotos:image];
});
});
dispatch_release (getVenuePhotos);
}
Here is how I implemented my Protocol in my POIPhoto.h
#protocol POIPhotoProtocol <NSObject>
-(void)gotVenuePhotos:(UIImage *)image;
#end
#interface POIPhoto : NSObject
-(void)getVenuePhotos:(NSString *)venueID;
#property(nonatomic, weak) id <POIPhotoProtocol> delegate;
#end
And in my class I want the call back
#interface PoiDetailViewController : UIViewController <POIPhotoProtocol>
And finaly I implement the protocol method
-(void)gotVenuePhotos:(UIImage *)image
{
self.venuePhoto.image = image;
}
The problem is that the gotVenuePhotos never gets called even though in my image downloader the [self.delegate gotVenuePhotos:image]; gets called
The issue is happening because you are not setting the delegate.
In your viewDidLoad set the delegate like:
self.delegate = self;

AdMob in iOS with UIWebView

I'm using the latest Xcode (4.4.1) and developing for iOS 5.1. I am utilizing the bottom tab bar interface provided by Apple. One of the tabs uses a UIWebView that utilizes the full screen space. When I try to add a standard banner provided by AdMob, it does not add a banner at all. I was following along with: https://developers.google.com/mobile-ads-sdk/docs/admob/fundamentals. Code attached below
About.h
#import <UIKit/UIKit.h>
#import "GADBannerView.h"
#interface About : UIViewController <UIWebViewDelegate> {
IBOutlet UIWebView *webView;
// Declare one as an instance variable
GADBannerView *bannerView_;
}
#property (nonatomic, retain) UIWebView *webView;
#end
About.m
#import "About.h"
#import "GADBannerView.h"
#import "GADRequest.h"
#import "constants.h"
#implementation About
#synthesize webView;
//#synthesize bannerView = bannerView_;
+ (void)initialize {
// Set user agent (the only problem is that we can't modify the User-Agent later in the program)
NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:UserAgent, #"UserAgent", nil];
[[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];
}
- (void)viewDidLoad {
[super viewDidLoad];
NSString *fullURL = ([IsBeta isEqualToString: #"true"]) ? #"http://beta.wouldyouratherapp.com/questions/index/0/1" : #"http://wouldyouratherapp.com/questions/index/0/1";
NSURL *url = [NSURL URLWithString:fullURL]; NSURLRequest *requestObj = [NSURLRequest requestWithURL:url]; [webView loadRequest:requestObj];
// Create a view of the standard size at the bottom of the screen.
// Available AdSize constants are explained in GADAdSize.h.
bannerView_ = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
// Specify the ad's "unit identifier." This is your AdMob Publisher ID.
bannerView_.adUnitID = MyAdUnitID;
// Let the runtime know which UIViewController to restore after taking
// the user wherever the ad goes and add it to the view hierarchy.
bannerView_.rootViewController = self;
[self.view addSubview:bannerView_];
// Initiate a generic request to load it with an ad.
[bannerView_ loadRequest:[GADRequest request]];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
#end
Yes, I have added all the frameworks already, and MyAdUnitID is already defined in the constants file, so everything SHOULD be working, but I guess I am missing something. Any help?
If you're adding the bannerView_, you'll have to decrease the height of your webView accordingly to make room for the bannerView_. Since the origin of the ad looks like its at (0,0), you probably want something similar to this in your adView:DidReceiveAd: callback:
webView.frame = CGRectMake (0, bannerView_.frame.size.height, webView.frame.size.width, webView.frame.size.height - bannerView_.frame.size.height);