iOS photo album permissions nativescript - ios

Hello I am attempting to access the user photo album on iOS in order for users to select a profile pic in my app.
I am using native script and I cannot figure out how to request permission to do so. My error is:
CONSOLE LOG file:///app/shared/user-view-model/user-view-model.js:96:28: fileUri: file:///var/mobile/Media/DCIM/100APPLE/IMG_0002.JPG
CONSOLE LOG file:///app/shared/user-view-model/user-view-model.js:101:24: NSErrorWrapper: You don’t have permission to save the file “100APPLE” in the folder “DCIM”.
I used
<key>NSPhotoLibraryUsageDescription</key>
<string> ${PRODUCT_NAME} photo use</string>
in my info.plist but no luck. Does anybody know what I'm missing?
var frame = require("ui/frame");
var platform = require("platform");
var firebase = require("nativescript-plugin-firebase");
var page;
var list;
function pageLoaded(args) {
page = args.object;
list = page.getViewById("urls-list");
}
exports.pageLoaded = pageLoaded;
function onSelectMultipleTap(args) {
var imagepicker = require("nativescript-imagepicker");
var context = imagepicker.create({
mode: "multiple"
});
startSelection(context);
}
exports.onSelectMultipleTap = onSelectMultipleTap;
function onSelectSingleTap(args) {
var imagepicker = require("nativescript-imagepicker");
var context = imagepicker.create({
mode: "single"
});
startSelection(context);
}
exports.onSelectSingleTap = onSelectSingleTap;
function startSelection(context) {
context
.authorize()
.then(function() {
list.items = [];
return context.present();
})
.then(function(selection) {
console.log("Selection done:");
selection.forEach(function(selected) {
console.log("----------------");
console.log("uri: " + selected.uri);
console.log("fileUri: " + selected.fileUri);
uploadImage(selected.fileUri);
});
list.items = selection;
}).catch(function (e) {
console.log(e);
});
}
function uploadImage(imageUrl){
firebase.uploadFile({
remoteFullPath: "test/testimage.jpg",
localFullPath: imageUrl,
onProgress: function(status) {
console.log("Uploaded fraction: " + status.fractionCompleted);
console.log("Percentage complete: " + status.percentageCompleted);
}
}).then((success) => {
console.log("success: " + success);
}, (error) => {
console.log("Error: " + error);
})
}

You need this requestAuthorization
PHPhotoLibrary.requestAuthorization(function (result) {
if (result === PHAuthorizationStatus.PHAuthorizationStatusAuthorized) {
// OK
} else {
// no permissions!
}
});
You also need this in your info.plist
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string></string>
</dict>

I found a solution from this github post
https://github.com/NativeScript/sample-ImageUpload/issues/2#issuecomment-252795778
The solution was to use the getImage() method and then saveToFile method on the result.
private selectImage(context){
context.authorize()
.then(() => {return context.present()})
.then((selection) => {
selection.forEach((selected) => {
selected.getImage()
.then((imageSource) => {
var appPath = fs.knownFolders.currentApp().path;
var profilePath = "/img/profile.jpg";
var filePath = fs.path.join(appPath, profilePath);
var saved = imageSource.saveToFile(filePath, enums.ImageFormat.jpeg);
console.log(`item saved:${saved}`);
console.log("FilePath: " + filePath);
console.log("Image source " + JSON.stringify(imageSource));
},
(error) => {
console.log("error");
})
})
})
}

Related

convert from video uri to blob is not working on iOS using ionic framework

I am using the following code to convert the video file to blob for iOS.
Takevideo()
{
const options: CameraOptions = {
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
destinationType: this.camera.DestinationType.DATA_URL,
mediaType: this.camera.MediaType.VIDEO
}
this.camera.getPicture(options).then(async (videoUrl) => {
debugger;
this.selectvideopath=null;
var filename = videoUrl.substr(videoUrl.lastIndexOf('/') + 1);
var dirpath = videoUrl.substr(0, videoUrl.lastIndexOf('/') + 1);
dirpath = dirpath.includes("file://") ? dirpath : "file://" + dirpath;
try {
var dirUrl = await this.file.resolveDirectoryUrl(dirpath);
var retrievedFile = await this.file.getFile(dirUrl, filename, {});
this.makeFileIntoBlob(retrievedFile.nativeURL);
} catch(err) {
return this.ionLoader.showAlert("Something went wrong.");
}
}, (err) => {
// Handle error
});
}
makeFileIntoBlob(_imagePath) {
return new Promise((resolve, reject) => {
console.log("makefileintoblob", +_imagePath);
let fileName = "";
this.file
.resolveLocalFilesystemUrl(_imagePath)
.then(fileEntry => {
let { name, nativeURL } = fileEntry;
let path = nativeURL.substring(0, nativeURL.lastIndexOf("/"));
console.log("path", path);
console.log("fileName", name);
fileName = name;
var buffer=this.file.readAsArrayBuffer(path, name);
console.log("makefileintoblob buffer: " +buffer);
this.Videodatas.push({vdodata:buffer});
return this.file.readAsArrayBuffer(path, name);
})
.then(buffer => {
this.ionLoader.showAlert('2:'+buffer);
console.log("makefileintoblob buffernew: " +buffer);
let imgBlob = new Blob([buffer], {
type: "video/MOV"
});
console.log(imgBlob.type, imgBlob.size);
resolve({
fileName,
imgBlob
});
})
.catch(e => reject(e));
});
}
But the following block is not executed.
.then(buffer => {
this.ionLoader.showAlert('2:'+buffer);
console.log("makefileintoblob buffernew: " +buffer);
let imgBlob = new Blob([buffer], {
type: "video/MOV"
});
console.log(imgBlob.type, imgBlob.size);
resolve({
fileName,
imgBlob
});
I have already installed the packages:
npm install --save #ionic-native/file-transfer
npm install cordova-plugin-file-transfer
npm install cordova-plugin-file
Can anyone please help me to resolve this issue.

react-native postId null from ShareDialog

I'm using react-native-fbsdk {ShareDialog} to post my feeds on Facebook but ShareDialog is not returning the post Id it's always null in my case.
My Import
import { ShareDialog, LoginManager, AccessToken, LoginButton } from "react-native-fbsdk";
This is my code
const shareLinkContent = {
contentType: 'link',
contentUrl: 'https://www.niofox.com/',
contentDescription: 'Test Sharing Description'
};
var tmp = this;
ShareDialog.canShow(shareLinkContent).then(
(canShow) => {
if (canShow) {
return ShareDialog.show(shareLinkContent);
}
}
).then(
(result) => {
if (result.isCancelled) {
alert('Share cancelled');
} else {
alert('Share success with postId: ' + JSON.stringify(result));
}
},
(error) => {
alert('Share fail with error: ' + error);
}
);

WebRTC - how to switch between getUserMedia and getDisplayMedia tracks inside RTCPeerConnection

I'm trying to develop an app where users can can video call to each other and share their screens using WebRTC technology. I have succeed with either video call or screen sharing app and now I'm trying to make it to be able to switch between getUserMedia and getDisplayMedia on button click during a call inside the same RTCPeerConnection but it doesn't work.
This is how I thought it could work:
function onLogin(success) {
var configuration = { offerToReceiveAudio: true, offerToReceiveVideo: true, "iceServers" : [ { "url" : "stun:stun.1.google.com:19302" } ] };
myConnection = window.RTCPeerConnection ? new RTCPeerConnection(configuration, { optional: [] }) : new RTCPeerConnection(configuration, { optional: [] });
myConnection.onicecandidate = function (event) {
console.log("onicecandidate");
if (event.candidate) send({ type: "candidate", candidate: event.candidate });
};
myConnection.ontrack=function(e){
try{remoteVideo.src = window.webkitURL?window.webkitURL.createObjectURL(e.streams[0]):window.URL.createObjectURL(e.streams[0])}
catch(err){remoteVideo.srcObject=e.streams[0]}
}
myConnection.ondatachannel=openDataChannel
openDataChannel();
startAVStream();
//startSStream()
};
function startAVStream(enable){
if(sStream)sStream.getTracks().forEach( function (track) {
try{myConnection.removeTrack( track, sStream );}
catch(e){}
} );
navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(s => {
if(!avStream){
avStream = s;
avStream.getTracks().forEach( function (track) {
myConnection.addTrack( track, avStream );
} );
}
}, function (error) { console.log(error); });
}
function startSStream(enable){
if(avStream)avStream.getTracks().forEach( function (track) {
try{myConnection.removeTrack( track, avStream );}
catch(e){}
} );
navigator.mediaDevices.getDisplayMedia({ video: true }).then(s => {
if(!sStream){
sStream = s;
sStream.getTracks().forEach( function (track) {
myConnection.addTrack( track, sStream );
} );
}
}, function (error) { console.log(error); });
}
Can anyone tell me how I can switch between tracks inside the same RTCPeerConnection or should I create 2 separate RTCPeerConnection - one for video/audio streaming and another for screen sharing?
Any help appreciated! Thanks!
You could use RTCRtpSender.replaceTrack to splice the screen capture track. This doesn't require renegotiation, and therefore has very low latency.
let newstream = navigator.mediaDevices.getDisplayMedia({});
let newtrack = newstream.getTracks()[1];
if(newtrack.kind !== 'video')
throw new Error('Eek!?');
pc.getSenders().forEach(async s => {
if(s.track && s.track.kind === 'video')
await s.replaceTrack(newtrack);
});
The test for s.track not being null deals with the case where you previously called replaceTrack(..., null).
shareScreen = () =>{
const success = (stream) => {
window.localStream = stream
// this.localVideoref.current.srcObject = stream
// localStream.replaceStream(stream);
this.setState({
localStream: stream
})
Object.values(this.state.peerConnections).forEach(pc => {
pc.getSenders().forEach(async s => {
console.log("s.track ",s.track);
if(s.track && s.track.kind === 'video'){
stream.getTracks().forEach(track => {
// pc.addTrack(track, this.state.localStream)
s.replaceTrack(track);
});
}
});
});
}
const failure = (e) => {
console.log('getUserMedia Error: ', e)
}
navigator.mediaDevices.getDisplayMedia({ cursor: true }).then(success).catch(failure)}

In app purchase 2 plugin ionic 3 for ios

I am very beginner in developing ionic apps and trying to integrate in-app-purchase2 plugin in ionic 3 for ios. Everytime my code stop and gives error this.store.when(productId).approved( (product: IAPProduct) => {}) is not a function.
This is my try that i do till now:
configurePurchasing() {
let productId;
try {
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
// Register Product
// Set Debug High
this.store.verbosity = this.store.DEBUG;
// Register the product with the store
this.store.register({
id: productId,
alias: productId,
type: this.store.CONSUMABLE
});
this.registerHandlers(productId);
this.store.ready().then((status) => {
console.log(JSON.stringify(this.store.get(productId)));
console.warn('Store is Ready: ' + JSON.stringify(status));
console.warn('Products: ' + JSON.stringify(this.store.products));
});
// Errors On The Specific Product
this.store.when(productId).error( (error) => {
alert('An Error Occured' + JSON.stringify(error));
});
// Refresh Always
console.log('Refresh Store');
this.store.refresh();
} catch (err) {
console.warn('Error On Store Issues' + JSON.stringify(err));
}
}
registerHandlers(productId) {
// Handlers
this.store.when(productId).approved( (product: IAPProduct) => {
// Purchase was approved
product.finish();
});
this.store.when(productId).registered( (product: IAPProduct) => {
console.warn('Registered: ' + JSON.stringify(product));
});
this.store.when(productId).updated( (product: IAPProduct) => {
console.warn('Loaded' + JSON.stringify(product));
});
this.store.when(productId).cancelled( (product) => {
alert('Purchase was Cancelled');
});
// Overall Store Error
this.store.error( (err) => {
alert('Store Error ' + JSON.stringify(err));
});
}
async purchase() {
let productId;
if (this.platform.is('ios')) {
productId = this.product.appleProductId;
} else if (this.platform.is('android')) {
productId = this.product.googleProductId;
}
console.log('Products: ' + JSON.stringify(this.store.products));
console.log('Ordering From Store: ' + productId);
try {
let product = this.store.get(productId);
alert('Product Info: ' + JSON.stringify(product));
// let order = await this.store.order(productId);
// alert('Finished Purchase');
} catch (err) {
console.log('Error Ordering ' + JSON.stringify(err));
}
}
From last 8 hours i am stuck at this point. Anyone here help me out in integrating this plugin. If you have any good tutorial related to this please post in comments. Thanks in advance.

Titaniuim: Facebook login event doesn't fire

I am trying to login through facebook.
I have all info in plist and in entitlelements file
So when I click to button it is redirecting safari facebook page and asking to confirm
When I click to OK it doesn’t fire ‘login’ event and it is not logged.
Currently I am testing on iOS 5s Simulator
Here is the code
var fbook = require('facebook');
fbook.appid = <MyAPP_ID>;
fbook.permissions = ['public_profile'];
//fbook.forceDialogAuth = true;
if (fbook.loggedIn) {
//progress.hide();
params = {
access_token : fbook.accessToken
};
fbook.requestWithGraphPath('/me', params, 'GET', function(e) {
var result = JSON.parse(e.result)
});
} else {
fbook.addEventListener('login', function(e) {
//alert('try to login');
if (e.success) {
//progress.hide();
params = {
access_token : fbook.accessToken
};
fbook.requestWithGraphPath('/me', params, 'GET', function(e) {
var result = JSON.parse(e.result);
Ti.API.info("Result is : " + e.result);
});
} else if (e.error) {
Ti.API.info("error");
//alert('Error: ' + e.error);
} else if (e.cancelled) {
Ti.API.info("cancelled");
}
});
fbook.authorize();
/*
fbook.addEventListener('logout', function(e) {
fbook.logout();
});*/
}

Resources