How to use connectionDidFinishDownloading:destinationURL: and connectionDidFinishLoading: - ios6

I have implemented both the NSURLConnectionDownloadDelegate, NSURLConnectionDataDelegate delegate methods as given below.
The problem is that after connection:didReceiveResponse: , connectionDidFinishDownloading:destinationURL: is called but not connectionDidFinishLoading: Even connection:didReceiveData: is not called.
When I comment the NSURLConnectionDownloadDelegate methods, the other three are called without any issues.
I have a NSURLConnections which gets JSON from server. The NSURLConnectionDataDownloading delegate methods are used by newsstand to download issues.
How do i manage this?
Here are all the delegate methods than I am implementing
- (void)connection:(NSURLConnection *)connection didWriteData:(long long)bytesWritten totalBytesWritten:(long long)totalBytesWritten expectedTotalBytes:(long long)expectedTotalBytes {
}
- (void)connectionDidFinishDownloading:(NSURLConnection *)connection destinationURL:(NSURL *)destinationURL {
}
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
}
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
}
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
}
Here is my .h file
#interface FirstTopViewController : UIViewController <NSURLConnectionDownloadDelegate, NSURLConnectionDataDelegate, NSURLConnectionDelegate, UITableViewDataSource, UITableViewDelegate>
This is how I am connecting to server to get JSON
[[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
This is the code for downloading an issue if needed
NSURLRequest *urlReq = [NSURLRequest requestWithURL:myURL];
NKAssetDownload *asset = [currentIssue addAssetWithRequest:urlReq];
[asset downloadWithDelegate:self];
The problem is with the call to get JSON from server. Issue downloading works fine.

NSURLConnectionDataDelegate define delegate methods used for loading data to memory.
NSURLConnectionDownloadDelegate: delegate methods used to perform resource downloads directly to a disk file.
Then if you implemented connectionDidFinishDownloading:destinationURL: in your delegate. That will inform NSURLConnection you want to download the data to a disk file other than to memory as NSData. The
NSURLConnectionDataDelegate method won't get called. If you eliminate connectionDidFinishDownloading:destinationURL: from your delegate class implementation, connection:DidReceiveData: will get called instead.
For your case, implement two helper delegates for different usage.

When you want to get your JSON data in -connection:didReceiveData:, you need to set the delegate to an object which implements NSURLConnectionDataDelegate; when you want to download an issue to a file, the delegate needs to be an object that implements NSURLConnectionDownloadDelegate. A single class can't do both at once.
This is not explained very well in the NSURLConnection docs, but the comments in NSURLConnection.h make it a little more explicit:
An NSURLConnection may be used for loading of resource data
directly to memory, in which case an
NSURLConnectionDataDelegate should be supplied, or for
downloading of resource data directly to a file, in which case
an NSURLConnectionDownloadDelegate is used. The delegate is
retained by the NSURLConnection until a terminal condition is
encountered. These two delegates are logically subclasses of
the base protocol, NSURLConnectionDelegate.

Related

Non Serializable object in Apache Flink

I am using Apache Flink to perform analytics on streaming data.
I am using a dependency whose object takes more than 10 secs to create as it is reads several files present in hdfs before initialisation.
If I initialise the object in open method I get a timeout Exception and if in the constructor of a sink/flatmap, I get serialisation exception.
Currently I am using static block to initialise the object in some other class, using Preconditions.checkNotNull(MGenerator.mGenerator) in main file and then it's working if used in a flatmap of sink.
Is there a way to create a non serializable dependency's object which might take more than 10 secs to be initialised in Flink's flatmap or sink?
public class DependencyWrap {
static MGenerator mGenerator;
static {
final String configStr = "{}";
final Config config = new Gson().fromJson(config, Config.class);
mGenerator = new MGenerator(config);
}
}
public class MyStreaming {
public static void main(String[] args) throws Exception {
Preconditions.checkNotNull(MGenerator.mGenerator);
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(parallelism);
...
input.flatMap(new RichFlatMapFunction<Map<String,Object>,List<String>>() {
#Override
public void open(Configuration parameters) {
}
#Override
public void flatMap(Map<String,Object> value, Collector<List<String>> out) throws Exception {
out.collect(MFVGenerator.mfvGenerator.generateMyResult(value.f0, value.f1));
}
});
}
}
Also, Please correct me if I am wrong about the question.
Doing it in the Open method is 100% the right way to do it. Is Flink giving you a timeout exception, or the object?
As a last ditch method, you could wrap your object in a class that contains both the object and it's JSON string or Config (is Config serializable?) with the object marked transient and then override the ReadObject/WriteObject methods to call the constructor. If the mGenerator object itself is stateless (and you'll have other problems if it's not), the serialization code should get called only once when jobs are distributed to taskmanagers.
Using open is usually the right place to load external lookup sources. The timeout is a bit odd, maybe there is a configuration around it.
However, if it's huge using a static loader (either static class as you did or singleton) has the benefit that you only need to load it once for all parallel instances of the task on the same task manager. Hence, you save memory and CPU time. This is especially true for you, as you use the same data structure in two separate tasks. Further, the static loader can be lazily initialized when it's used for the first time to avoid the timeout in open.
The clear downside of this approach is that the testability of your code suffers. There are some ways around that, which I could expand if there is interest.
I don't see a benefit of using the proxy serializer pattern. It's unnecessarily complex (custom serialization in Java) and offers little benefit.

Registering dependencies within TinyIOC for use in NancyFX

I have another newbie question regarding registering additional dependencies within TinyIoc for use within NancyFX.
I am continuing to get the following exceptions when running the application...
Unable to resolve type: AdvancedSearchService.Interfaces.IResponseFactory
Exception Details: TinyIoC.TinyIoCResolutionException: Unable to resolve type: AdvancedSearchService.Interfaces.IResponseFactory
Source Error:
Line 25: var container = TinyIoCContainer.Current;
Line 26:
Line 27: _responseFactory = container.Resolve<IResponseFactory>();
Line 28:
Line 29:
I am currently registering my dependencies incorrectly, but I cannot seem to figure out the correct way. Below is my code within my custom bootstrapper. Also note that I am not currently calling the base.ConfigureRequestContainer method because I cannot seem to figure out how to get the current context to pass into it.
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
container.Register<IRavenSessionManager>(new RavenSessionManager());
base.ConfigureApplicationContainer(container);
ConfigureRequestContainer(container);
}
protected void ConfigureRequestContainer(TinyIoCContainer applicationContainer)
{
var requestContainer = applicationContainer.GetChildContainer();
requestContainer.Register<ISearchRepository>(new SearchRepository(requestContainer.Resolve<IRavenSessionManager>().GetSession()));
requestContainer.Register<IResponseFactory>(new ResponseFactory(requestContainer.Resolve<ISearchRepository>()));
//base.ConfigureRequestContainer(requestContainer,[I NEED THE CONTEXT])
}
Any help would really be appreciated...apparently my ignorance has no limits :)
Ok, not 100% sure where to start.. you don't need the context because you're doing it wrong :-)
Firstly, why are you calling "configure request container" at all, and why are you creating a child container? You don't do that :-) There are two scopes, application scope, configured by overriding ConfigureApplicationContainer, and request scope, configured by overriding ConfigureRequestContainer, you don't call them yourself, you just override them depending on how you want to scope your objects.
Secondly, the default Nancy bootstrapper will "autoregister" everything it can in its default implementation of ConfigureApplicationContainer. By calling "base" after you've made a manual registration you are effectively copying over your original registration by autoregister. Either don't call base, or call it before you do your manual registrations. And, again, don't call ConfigureRequestContainer from your ConfigureApplicationContainer :-)
If you don't care about everything being application scoped (so singetons get the same instance for each request) then you don't need any of this, you can just rely on autoregister.
You're currently constructing your objects manually and putting them into the container, that seems a rather odd way to do it. Normally you'd just register the types and let the container handle instantiating as and when it needs to.
You're not overriding ConfigureRequestContainer, you are just creating a new method (with a different signature).
So, what you probably want is something like:
protected override void ConfigureApplicationContainer(TinyIoCContainer container)
{
base.ConfigureApplicationContainer(container);
// Autoregister will actually do this for us, so we don't need this line,
// but I'll keep it here to demonstrate. By Default anything registered
// against an interface will be a singleton instance.
container.Register<IRavenSessionManager, RavenSessionManager>();
}
// Need to override this, not just make a new method
protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
{
// Get our session manager - this will "bubble up" to the parent container
// and get our application scope singleton
var session = container.Resolve<IRavenSessionManager>().GetSession();
// We can put this in context.items and it will be disposed when the request ends
// assuming it implements IDisposable.
context.Items["RavenSession"] = session;
// Just guessing what this type is called
container.Register<IRavenSession>(session);
container.Register<ISearchRepository, SearchRepository>();
container.Register<IResponseFactory, ResponseFactory>();
}

Silverlight webclient downloadstringasync question

I'm trying to put together a simple RSS feed reader in windows phone 7 but I'm struggling to understand how the async model works.
What I have is a helper class that when I pass it a URL will parse and build up a ViewModel object and return it. So what I am trying to acheive is this:
public static class FeedHelper
{
public static FeedViewModel LoadFeed(string url)
{
//parse rss feed and return view model
}
}
In the loadfeed method I would make a webclient object and build up the FeedViewModel. However because the WebClient's DownloadStringAsync is async and the result is returned to another method I can't figure out how I can return the FeedViewModel from my LoadFeed method.
Any examples or links to blog posts would be appreciated. I've done quite a bit of googling but can't find any examples of how I would approach this problem.
You cannot return the ViewModel from your LoadFeed function because as you discovered, the call is async.
You have several choices, for ex. you could:
make the LoadFeed method non-static and put it into a class (for ex. FeedRetriever)
in the FeedRetriever class expose an event (or a command) "FeedLoaded"
in your ViewModel repository subscribe to that event/command and take the ViewModel in the handler
You will need to setup the WebClient's DownloadStringCompleted event handler to do the processing of the RSS feed. Note that WebClient returns on the UI thread and you are safe from cross-thread exceptions. Here is the snippet of code that goes into the LoadFeed method -
WebClient wc = new WebClient();
wc.DownloadStringCompleted += new DownloadStringCompleteEventHandler(DownloadSettingsComplete);
wc.DownloadStringAsync(uri);
There are two sets of articles that will help you in buiding an RSS reader -
Eugene Chaikin has built a simple RSS reader that uses WebClient.
Dennis Delimarsky has a two part article on building a RSS reader - part 1, part 2
HTH, indyfromoz

How to dynamically discover all XAML files in all modules in a Silverlight prism app

Is there an easy way to dynamically discover all the XAMLs files within all the currently loaded modules (specifically of a Silverlight Prism application)? I am sure this is possible, but not sure where to start.
This has to occur on the Silverlight client: We could of course parse the projects on the dev machine, but that would reduce the flexibility and would include unused files in the search.
Basically we want to be able to parse all XAML files in a very large Prism project (independent of loading them) to identify all localisation strings. This will let us build up an initial localisation database that includes all our resource-binding strings and also create a lookup of which XAML files they occur in (to make editing easy for translators).
Why do this?: The worst thing for translators is to change a string in one context only to find it was used elsewhere with slightly different meaning. We are enabling in-context editing of translations from within the application itself.
Update (14 Sep):
The standard method for iterating assemblies is not available to Silverlight due to security restrictions. This means the only improvement to the solution below would be to cooperate with the Prism module management if possible. If anyone wants to provide a code solution for that last part of this problem there are points available to share with you!
Follow-up:
Iterating content of XAP files in a module-base project seems like a really handy thing to be able to do for various reasons, so putting up another 100 rep to get a real answer (preferably working example code). Cheers and good luck!
Partial solution below (working but not optimal):
Below is the code I have come up with, which is a paste together of techniques from this link on Embedded resources (as suggested by Otaku) and my own iterating of the Prism Module Catalogue.
Problem 1 - all the modules are
already loaded so this is basically
having to download them all a second
time as I can't work out how to
iterate all currently loaded Prism modules.
If anyone wants to share the bounty
on this one, you still can help make
this a complete solution!
Problem 2 - There is apparently a bug
in the ResourceManager that requires
you to get the stream of a known
resource before it will let you
iterate all resource items (see note in the code below). This means I have to have a dummy resource file in every module. It would be nice to know why that initial GetStream call is required (or how to avoid it).
private void ParseAllXamlInAllModules()
{
IModuleCatalog mm = this.UnityContainer.Resolve<IModuleCatalog>();
foreach (var module in mm.Modules)
{
string xap = module.Ref;
WebClient wc = new WebClient();
wc.OpenReadCompleted += (s, args) =>
{
if (args.Error == null)
{
var resourceInfo = new StreamResourceInfo(args.Result, null);
var file = new Uri("AppManifest.xaml", UriKind.Relative);
var stream = System.Windows.Application.GetResourceStream(resourceInfo, file);
XmlReader reader = XmlReader.Create(stream.Stream);
var parts = new AssemblyPartCollection();
if (reader.Read())
{
reader.ReadStartElement();
if (reader.ReadToNextSibling("Deployment.Parts"))
{
while (reader.ReadToFollowing("AssemblyPart"))
{
parts.Add(new AssemblyPart() { Source = reader.GetAttribute("Source") });
}
}
}
foreach (var part in parts)
{
var info = new StreamResourceInfo(args.Result, null);
Assembly assy = part.Load(System.Windows.Application.GetResourceStream(info, new Uri(part.Source, UriKind.Relative)).Stream);
// Get embedded resource names
string[] resources = assy.GetManifestResourceNames();
foreach (var resource in resources)
{
if (!resource.Contains("DummyResource.xaml"))
{
// to get the actual values - create the table
var table = new Dictionary<string, Stream>();
// All resources have “.resources” in the name – so remove it
var rm = new ResourceManager(resource.Replace(".resources", String.Empty), assy);
// Seems like some issue here, but without getting any real stream next statement doesn't work....
var dummy = rm.GetStream("DummyResource.xaml");
var rs = rm.GetResourceSet(Thread.CurrentThread.CurrentUICulture, false, true);
IDictionaryEnumerator enumerator = rs.GetEnumerator();
while (enumerator.MoveNext())
{
if (enumerator.Key.ToString().EndsWith(".xaml"))
{
table.Add(enumerator.Key.ToString(), enumerator.Value as Stream);
}
}
foreach (var xaml in table)
{
TextReader xamlreader = new StreamReader(xaml.Value);
string content = xamlreader.ReadToEnd();
{
// This is where I do the actual work on the XAML content
}
}
}
}
}
}
};
// Do the actual read to trigger the above callback code
wc.OpenReadAsync(new Uri(xap, UriKind.RelativeOrAbsolute));
}
}
Use GetManifestResourceNames reflection and parse from there to get only those ending with .xaml. Here's an example of using GetManifestResourceNames: Enumerating embedded resources. Although the sample is showing how to do this with a seperate .xap, you can do this with the loaded one.
I've seen people complain about some pretty gross bugs in Prism
Disecting your problems:
Problem 1: I am not familiar with Prism but from an object-oriented perspective your Module Manager class should keep track of whether a Module has been loaded and if not already loaded allow you to recursively load other Modules using a map function on the List<Module> or whatever type Prism uses to represent assemblies abstractly. In short, have your Module Manager implement a hidden state that represents the List of Modules loaded. Your Map function should then take that List of Modules already loaded as a seed value, and give back the List of Modules that haven't been loaded. You can then either internalize the logic for a public LoadAllModules method or allow someone to iterate a public List<UnloadedModule> where UnloadedModule : Module and let them choose what to load. I would not recommend exposing both methods simultaneously due to concurrency concerns when the Module Manager is accessed via multiple threads.
Problem 2: The initial GetStream call is required because ResourceManager lazily evaluates the resources. Intuitively, my guess is the reason for this is that satellite assemblies can contain multiple locale-specific modules, and if all of these modules were loaded into memory at once it could exhaust the heap, and the fact these are unmanaged resources. You can look at the code using RedGate's .NET Reflector to determine the details. There might be a cheaper method you can call than GetStream. You might also be able to trigger it to load the assembly by tricking it by loading a resource that is in every Silverlight assembly. Try ResourceManager.GetObject("TOOLBAR_ICON") or maybe ResourceManager.GetStream("TOOLBAR_ICON") -- Note that I have not tried this and am typing this suggestion as I am about to leave for the day. My rationale for it being consistently faster than your SomeDummy.Xaml
approach is that I believe TOOLBAR_ICON is hardwired to be the zeroth resource in every assembly. Thus it will be read very early in the Stream. Faaaaaast. So it is not just avoiding needing SomeDummy.Xaml in every assembly of your project that I am suggesting; I am also recommending micro-optimizations.
If these tricks work, you should be able to significantly improve performance.
Additional thoughts:
I think you can clean up your code further.
IModuleCatalog mm = this.UnityContainer.Resolve<IModuleCatalog>();
foreach (var module in mm.Modules)
{
could be refactored to remove the reference to UnityContainer. In addition, IModuleCatalog would be instantiated via a wrapper around the List<Module> I mentioned in my reply to Problem 1. In other words, the IModuleCatalog would be a dynamic view of all loaded modules. I am assuming there is still more performance that can be pulled out of this design, but at least you are no longer dependent on Unity. That will help you better refactor your code later on for more performance gains.

Windows Phone 7 App Quits when I attempt to deserialize JSON

I'm developing my first windows phone 7 app, and I've hit a snag. basically it's just reading a json string of events and binding that to a list (using the list app starting point)
public void Load()
{
// form the URI
UriBuilder uri = new UriBuilder("http://mysite.com/events.json");
WebClient proxy = new WebClient();
proxy.OpenReadCompleted += new OpenReadCompletedEventHandler(OnReadCompleted);
proxy.OpenReadAsync(uri.Uri);
}
void OnReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
var serializer = new DataContractJsonSerializer(typeof(EventList));
var events = (EventList)serializer.ReadObject(e.Result);
foreach (var ev in events)
{
Items.Add(ev);
}
}
}
public ObservableCollection<EventDetails> Items { get; private set; }
EventDetails is my class that wraps the json string. this class has to be correct because it is an exact copy of the class used by that website internally from which the json is generated...
I get the json string correctly from the webclient call (I read the memorystream and the json is indeed there) but as soon as I attempt to deserialize the string, the application exits and the debugger stops.
I get no error message or any indication that anything happen, it just stops. This happens if I type the deserialize method into the watch window as well...
I have already tried using JSON.net in fact I thought maybe it was a problem with JSON.net so I converted it to use the native deserializer in the .net framework but the error is the same either way.
why would the application just quit? shouldn't it give me SOME kind of error message?
what could I be doing wrong?
many thanks!
Firstly, the fact that you have some string there that looks like JSON does not mean that you have a valid JSON. Try converting a simple one.
If your JSON is valid, it might be that your JSON implementation does not know how to convert a list to EventList. Give it a try with ArrayList instead and let me know.
The application closes because an unhandled exception happens. If check the App.xaml.cs file you will find the code that closes your app. What you need to do is try catch your deserialization process and handle it locally. So most likely you have some JSON the DataContractJsonSerializer does not like. I have been having issue with it deserializing WCF JSON and have had to go other routes.
You may want to check to ensure your JSON is valid, just because your website likes it does not mean it is actually valid, the code on your site may be helping to correct the issue. Drop a copy of your JSON object (the string) in http://jsonlint.com/ to see if it is valid or not. Crokford (the guy who created JSON) wrote this site to validate JSON, so I would rely on it more than your site ;) This little site has really helped me out of some issues over the past year.
I ran into this same kind of problem when trying to migrate some existing WM code to run on WP7. I believe that the WP7 app crashes whenever it loads an assembly (or class?) that references something that's not available in WP7. In my case, I think it was Assembly.Load or something in the System.IO namespace, related to file access via paths.
While your case might be something completely different, the symptoms were exactly the same.
The only thing I can recommend is to go through the JSON library and see if it's referencing base classes that are not allowed in WP7. Note that it doesn't even have to hit the line of code that's causing the issue - it'll crash as soon as it tries to hit the class that contains the bad reference.
If you can step into the JSON library, you can get a better idea of which class is causing the problem, because as soon as the code references it, the whole app will crash and the debugger will stop.

Resources