I am trying to use QLPreviewController to see a PDF file and send it, but I have an issue with the action button after previewing the PDF document.
When I press the action button (at the top right) app crashes and I get: "Unhandled managed exception: Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: UIDocumentInteractionController: invalid scheme (null). Only the file scheme is supported. (MonoTouch.Foundation.MonoTouchException)"
I did some research and it seams that this issue may occur if you download a file from the internet or if the file type is not "file:// .......... ".
My NSUrl is on that format so I dont know why I have this error.
Anybody has any idea?
Thanks
Here is my code to call the Controller:
QLPreviewController previewController= new QLPreviewController();
previewController.DataSource=new MyQLPreviewControllerDataSource();
this.PresentViewController(previewController,true, null);
This is my code for the DataSource:
public class MyQLPreviewControllerDataSource : QLPreviewControllerDataSource { public override int PreviewItemCount (QLPreviewController controller) {
return 1;
}
public override QLPreviewItem GetPreviewItem (QLPreviewController controller, int index)
{
string fileName = #"example.pdf";
var documents = Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments);
var library = Path.Combine (documents,fileName);
NSUrl url = NSUrl.FromFilename (library);
return new QlItem ("Title", url);
}
}
This is my code for the item:
public class QlItem : QLPreviewItem { string _title; Uri _uri;
public QlItem (string title, Uri uri)
{
this._title = title;
this._uri = uri;
}
public override string ItemTitle {
get { return _title; }
}
public override NSUrl ItemUrl {
get { return _uri; }
}
}
Your QlItem class is casting the original NSUrl into a Uri before casting it back into a NSUrl and something is getting lost along the way.
It should look more like:
public class QlItem : QLPreviewItem
{
string title;
NSUrl uri;
public QlItem(string title, NSUrl uri)
{
this.title = title;
this.uri = uri;
}
public override string ItemTitle {
get { return title; }
}
public override NSUrl ItemUrl {
get { return uri; }
}
}
Related
I am using QuickLook to preview Images, Pdf and Microsoft office documents. It is working fine to preview documents but its ShouldOpenUrl delegate method not firing whenever i try to open link from documents. Following is the code that i tried.
I test my app with iPhone and iPad having iOS v11.
// Open documents using title and file url
public void OpenDocument(string title, string url)
{
var rootViewController = UIApplication.SharedApplication.KeyWindow.RootViewController;
var previewViewController = new QLPreviewController();
previewViewController.DataSource = new DocumentPreviewDataSource(title, url);
previewViewController.Delegate = new PreviewControllerDelegate();
rootViewController.PresentViewController(previewViewController, true, null);
}
// QLPreviewControllerDelegate Implementation
public class PreviewControllerDelegate : QLPreviewControllerDelegate
{
public override bool ShouldOpenUrl(QLPreviewController controller, NSUrl url, IQLPreviewItem item)
{
Console.WriteLine("PreviewControllerDelegate::ShouldOpenUrl: {0}", url.AbsoluteString);
return true;
}
}
You can use the weakdelegate
public partial class xxxViewController : UIViewController,IQLPreviewControllerDelegate,IQLPreviewControllerDataSource
//. . .
in method OpenDocument
public void OpenDocument()
{
var previewViewController = new QLPreviewController();
previewViewController.View.Frame = View.Bounds;
previewViewController.WeakDelegate = this;
previewViewController.WeakDataSource = this;
this.PresentViewController(previewViewController, true,null);
}
And override the method in QLPreviewControllerDelegate and QLPreviewControllerDataSource
public nint PreviewItemCount(QLPreviewController controller)
{
return 1;
}
public IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)
{
return new NSUrl("your url");
}
[Export("previewController:shouldOpenURL:forPreviewItem:")]
public bool ShouldOpenUrl(QLPreviewController controller, NSUrl url, IQLPreviewItem item)
{
Console.WriteLine("PreviewControllerDelegate::ShouldOpenUrl: {0}", url.AbsoluteString);
return true;
}
[Export("previewControllerWillDismiss:")]
public void WillDismiss(QLPreviewController controller)
{
// do some thing
}
I use the above code and it works fine.
I'm working at mvc.net web application and I'm using urlrewritingNet for route urls.
I want to change some characters of url before urlrewriting reach url.
ex:
user request this url /Prods/1/Medi_lice.aspx
I want this url to be /Prods/1/Medi-lice before rewriting process.
Thanks
Edit
My question is: I want to change last segment of my url. I want the underscore to be dash
I write HttpModule to work around:
public class PageNameProcessingModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.LogRequest += new EventHandler(App_Handler);
context.PostLogRequest += new EventHandler(App_Handler);
}
public void App_Handler(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpContext context = app.Context;
if (context.CurrentNotification == RequestNotification.LogRequest)
{
if (!context.IsPostNotification)
{
var url = context.Request.Url.AbsolutePath;
var segments = context.Request.Url.Segments;
var lastSeg = segments[segments.Length - 1];
segments[segments.Length - 1] = lastSeg.Replace("_", "-");
// here I want an approach to set new url
// or pass the new url to the UrlRewriting
// this is urlrewriting namespace UrlRewritingNet.Configuration
}
else
{
}
}
}
}
Try context.RewritePath method
I found the solution for my question after I read urlrewriting pdf
I did the following:
Write a custom provider
Write custom rewrite rule.
Update configs at web.config
Here is the custom provider:
public class CustomReWriteProvider : UrlRewritingNet.Configuration.Provider.UrlRewritingProvider
{
public override UrlRewritingNet.Web.RewriteRule CreateRewriteRule()
{
return new CustomRegexReWriteRule();
}
}
And here is the custom rewrite rule:
public class CustomRegexReWriteRule : UrlRewritingNet.Web.RewriteRule
{
public override void Initialize(UrlRewritingNet.Configuration.RewriteSettings rewriteSettings)
{
base.Initialize(rewriteSettings);
this.RegexOptions = rewriteSettings.GetEnumAttribute<RegexOptions>("regexOptions", RegexOptions.None);
this.VirtualUrl = rewriteSettings.GetAttribute("virtualUrl", "");
this.destinationUrl = rewriteSettings.GetAttribute("destinationUrl", "");
}
public override bool IsRewrite(string requestUrl)
{
return this.regex.IsMatch(requestUrl);
}
public override string RewriteUrl(string url)
{
string newUrl = url;
if (url.ToLower().EndsWith(".aspx"))
{
Uri uri = new Uri("http://example.com" + url);
var segments = uri.Segments;
var lastSeg = segments[segments.Length - 1];
var name = lastSeg.Remove(lastSeg.Length - 5);
if (!name.IsNumbersOnly())
{
segments[segments.Length - 1] = lastSeg.Replace("_", "-");
newUrl = string.Join("", segments) + uri.Query;
}
}
return this.regex.Replace(newUrl, destinationUrl, 1);
}
private Regex regex;
private void CreateRegEx()
{
UrlHelper urlHelper = new UrlHelper();
if (IgnoreCase)
{
this.regex = new Regex(urlHelper.HandleRootOperator(virtualUrl), RegexOptions.IgnoreCase | RegexOptions.Compiled | regexOptions);
}
else
{
this.regex = new Regex(urlHelper.HandleRootOperator(virtualUrl), RegexOptions.Compiled | regexOptions);
}
}
private string virtualUrl = string.Empty;
public string VirtualUrl
{
get { return virtualUrl; }
set
{
virtualUrl = value;
CreateRegEx();
}
}
private string destinationUrl = string.Empty;
public string DestinationUrl
{
get { return destinationUrl; }
set { destinationUrl = value; }
}
private RegexOptions regexOptions = RegexOptions.None;
public RegexOptions RegexOptions
{
get { return regexOptions; }
set
{
regexOptions = value;
CreateRegEx();
}
}
}
And at the configs:
<urlrewritingnet rewriteOnlyVirtualUrls="true" contextItemsPrefix="QueryString" defaultProvider="CutsomProvider" xmlns="http://www.urlrewriting.net/schemas/config/2006/07" >
<providers>
<add name="CutsomProvider" type="MyNamespace.CustomReWriteProvider" />
</providers>
</urlrewritingnet>
And It worked for me.
I'm trying out MvvmCross with Xamarin 'classic'.
I've got it working with Android.
But I can't get it work for iOS. I've taken a look at the sample mentioned here (eh): MVVMCross support for Xamarin.iOS Storyboards
I'm really missing something.
What do i have:
A storyboard with only 3 controls on it. a label and 2 buttons. All 3
have names so i get the properties in the RootViewController class.
The basis setup.cs
AppDelegate.cs
[Register("AppDelegate")]
public partial class AppDelegate : MvxApplicationDelegate
{
UIWindow _window;
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
_window = new UIWindow(UIScreen.MainScreen.Bounds);
StoryBoardTouchViewPresenter sbPresenter = new StoryBoardTouchViewPresenter(this, _window, "MainStoryboard");
var setup = new Setup(this, _window);
setup.Initialize();
var startup = Mvx.Resolve<IMvxAppStart>();
startup.Start();
sbPresenter.MasterNavigationController.NavigationBar.Translucent = false;
sbPresenter.MasterNavigationController.SetNavigationBarHidden(false, false);
return true;
}
}
StoryBoardTouchViewPresenter (from MVVMCross: Is it possible to use Storyboard with ICommand navigation?) But the API is changed.
public class StoryBoardTouchViewPresenter : MvxTouchViewPresenter
{
public static UIStoryboard Storyboard = null;
public StoryBoardTouchViewPresenter(UIApplicationDelegate applicationDelegate, UIWindow window, string storyboardName, NSBundle StoryboardBundleOrNull = null)
: base(applicationDelegate, window)
{
Storyboard = UIStoryboard.FromName(storyboardName, StoryboardBundleOrNull);
}
public override void Show(IMvxTouchView view)
{
MvxViewController sbView = null;
try
{
sbView = (MvxViewController)Storyboard.InstantiateViewController(view.Request.ViewModelType.Name.Replace("Model", ""));
}
catch (Exception e)
{
Console.WriteLine("Failed to find storyboard view, did you forget to set the Storyboard ID to the ViewModel class name without the Model suffix ?" + e);
}
sbView.Request = view.Request;
base.Show(sbView);
}
}
The default App.cs in the Core project
public class App : Cirrious.MvvmCross.ViewModels.MvxApplication
{
public override void Initialize()
{
CreatableTypes()
.EndingWith("Service")
.AsInterfaces()
.RegisterAsLazySingleton();
RegisterAppStart<ViewModels.MainViewModel>();
}
}
The ViewModel:
public class MainViewModel : MvxViewModel
{
ITodoTaskService taskService;
IDataManager<TodoTask> tasks;
public MainViewModel(ITodoTaskService taskService)
{
this.taskService = taskService;
}
public async override void Start()
{
this.tasks = new DataManager<TodoTask>(await this.taskService.GetTodoTasksAsync());
this.tasks.MoveFirst();
Rebind();
base.Start();
}
private void Rebind()
{
this.Description = this.tasks.Current.Description;
NextCommand.RaiseCanExecuteChanged();
PreviousCommand.RaiseCanExecuteChanged();
}
private string description;
public string Description
{
get { return this.description; }
set
{
this.description = value;
RaisePropertyChanged(() => Description);
}
}
private MvxCommand nextCommand;
public MvxCommand NextCommand
{
get
{
this.nextCommand = this.nextCommand ?? new MvxCommand(NavigateToNext, CanNavigateNext);
return this.nextCommand;
}
}
private bool CanNavigateNext()
{
return this.tasks.CanMoveNext;
}
public void NavigateToNext()
{
this.tasks.MoveNext();
Rebind();
}
private MvxCommand previousCommand;
public MvxCommand PreviousCommand
{
get
{
this.previousCommand = this.previousCommand ?? new MvxCommand(NavigateToPrevious, CanNavigatePrevious);
return this.previousCommand;
}
}
private bool CanNavigatePrevious()
{
return this.tasks.CanMovePrevious;
}
public void NavigateToPrevious()
{
this.tasks.MovePrevious();
Rebind();
}
}
I tried all kind of things. At the moment i get an exception that the MainView cannot be found. Which i partly understand. in App.cs MainViewModel is the start up. But the controller is called RootViewController. I think the RootviewController should bind to my MainViewModel. But i don't know how.
How should I make MvvmCross with iOs working?
How should I name the parts?
MvvmCross' default view finder will look for a view called MainView. That view should be derived from MvxViewController or another IMvxTouchView type. If you don't want to name your view controller "MainView" then you need to create a custom view resolver.
My advice: just rename your RootViewController to MainView.
In my ASP.NET MVC application I have an action that returns LESS variables.
I would like to import these variables into my main LESS file.
What is the recommended approach for doing this since DotLess will only import files with .less or .css extensions?
I found the easiest solution was to implement IFileReader.
The implementation below makes a HTTP request to any LESS path prefixed with "~/assets", otherwise we use the default FileReader.
Note that this is prototype code:
public class HttpFileReader : IFileReader
{
private readonly FileReader inner;
public HttpFileReader(FileReader inner)
{
this.inner = inner;
}
public bool DoesFileExist(string fileName)
{
if (!fileName.StartsWith("~/assets"))
return inner.DoesFileExist(fileName);
using (var client = new CustomWebClient())
{
client.HeadOnly = true;
try
{
client.DownloadString(ConvertToAbsoluteUrl(fileName));
return true;
}
catch
{
return false;
}
}
}
public byte[] GetBinaryFileContents(string fileName)
{
throw new NotImplementedException();
}
public string GetFileContents(string fileName)
{
if (!fileName.StartsWith("~/assets"))
return inner.GetFileContents(fileName);
using (var client = new CustomWebClient())
{
try
{
var content = client.DownloadString(ConvertToAbsoluteUrl(fileName));
return content;
}
catch
{
return null;
}
}
}
private static string ConvertToAbsoluteUrl(string virtualPath)
{
return new Uri(HttpContext.Current.Request.Url,
VirtualPathUtility.ToAbsolute(virtualPath)).AbsoluteUri;
}
private class CustomWebClient : WebClient
{
public bool HeadOnly { get; set; }
protected override WebRequest GetWebRequest(Uri address)
{
var request = base.GetWebRequest(address);
if (HeadOnly && request.Method == "GET")
request.Method = "HEAD";
return request;
}
}
}
To register the reader, execute the following when your application starts:
var configuration = new WebConfigConfigurationLoader().GetConfiguration();
configuration.LessSource = typeof(HttpFileReader);
Can anyone tell me how to create an URL link in Blackberry, which opens a web page after it's been clicked?
// This can eb a nested class in your screen class.
class URLButtonField extends ButtonField {
String url;
public URLButtonField(String label, String url) {
super(label);
this.url = url;
}
public String getURL() {
return url;
}
public void setURL(String url) {
this.url = url;
}
}
// member variable of your screen class- this will let you access it later
// to change the URL
URLButtonField bf;
// In your screen's constructor:
bf = new ButtonField("Example", "http://www.example.com");
bf.setFieldChangeListener( new FieldChangeListener() {
void fieldChanged(Field field, int context) {
if (field == this) {
BrowserSession session =- Browser.getDefaultSession();
session.displayPage(getURL());
}
}
} );
add(bf);
You can then change the text or destination URL of "bf" at any time, and whatever you change it to will be the URL that is launched when it is clicked:
// In response to some activity:
bf.setText("Example Two");
bf.setURL("http://www.example.com/two");