geek-1001 / clue Goto Github PK
View Code? Open in Web Editor NEWFlexible bug report framework for iOS
License: MIT License
Flexible bug report framework for iOS
License: MIT License
Description
We should create a Writable
Swift protocol to replace CLUWritable
. This would allow to migrate, over a period of time, all classes dependent on CLUWritable
to Swift.
Depends on #11.
Description
Right now, we are using CLUVideoWriter
to write video content to file. We'd like to create a specific writer for video content (VideoWriter
) to better encapsulate this functionality.
Description
Right now, we are using CLUDataWriter
to write JSON content to file. We'd like to create a specific writer for JSON data (JSONDataWriter
) that allows to validate the content before writing to the file system. This new class should be used for all scenario where we are writing JSON data.
Hy,
In our codebase we enabled the Main Thread Checker:
You can found it:
Edit schema > Run > diagnostics > Runtime API Checking > [✔] Main Thread Checker
Produces a lot of warning around UIKit component getter/setters.
We need to fail some utils method in UIView (CLUViewRecordableAdditions)
if input arguments are invalid.
For example:
- (NSDictionary *)clue_fontPropertyDictionaryForFont:(UIFont *)font {
NSMutableDictionary *fontDictionary = [[NSMutableDictionary alloc] init];
if (font) {
[fontDictionary clue_setValidObject:font.familyName forKey:@"familyName"];
[fontDictionary clue_setValidObject:font.fontName forKey:@"fontName"];
[fontDictionary setObject:@(font.pointSize) forKey:@"pointSize"];
[fontDictionary setObject:@(font.lineHeight) forKey:@"lineHeight"];
}
return fontDictionary;
}
If user will pass invalid font – this method will return empty dictionary. But if font is invalid, we don't need font dictionary at all.
Here are some utils method from UIView (CLUViewRecordableAdditions)
which I think needs to be fixed (return nil if input argument is invalid)
-clue_fontPropertyDictionaryForFont:
-clue_attributedTextPropertyDictionaryForAttributedString:
-clue_colorPropertyDictionaryForColor:
Note : We need to check where those method used and ensure that we won't pass invalid object into dictionary for example.
We don't need empty dictionary if input argument is invalid.
Right now we are using JSONWriter
to write JSON data into the file from recordable/info modules. We need to create DataWriter
as a base class to leave an ability to write raw data into the file.
This will leave some flexibility and allow to encapsulate all low-level stream management code into DataWriter
instead of JSONWriter
.
There is a TODO comment in -clue_attributedTextPropertyDictionaryForAttributedString:
method in UIView(CLUViewRecordableAdditions)
to parse more useful properties from NSAttributedString
.
- (NSDictionary *)clue_attributedTextPropertyDictionaryForAttributedString:(NSAttributedString *)attributedText {
NSMutableDictionary *attributedTextDictionary = [[NSMutableDictionary alloc] init];
if (attributedText) {
[attributedTextDictionary clue_setValidObject:[attributedText string] forKey:@"string"];
}
// TODO: add Retrieving Attribute Information
return attributedTextDictionary;
}
Right now Clue parse only string
property which most of the time isn't enough.
+[CLURecordIndicatorViewManager currentViewController]
is a universal method which returns current top/active UIViewController
instance. Based on this method Clue can show Record indicator view, record only current view controller's view structure and use it as a main overall context for Clue framework.
Right now this method is a part of CLURecordIndicatorViewManager
class. But CLURecordIndicatorViewManager
is responsible only for managing CLURecordIndicatorView.
Here are places, where Clue use -currentViewController
method:
CLUViewStructureModule
to get current view controller and view stature data from it- (void)addNewFrameWithTimestamp:(CFTimeInterval)timestamp {
@synchronized (self) {
NSDictionary *currentViewStructure;
UIViewController *rootViewController = [CLURecordIndicatorViewManager currentViewController];
if (rootViewController && [rootViewController.view isKindOfClass:[UIView class]]) {
currentViewStructure = [rootViewController.view clue_viewPropertiesDictionary];
}
if (!_lastRecordedViewStructure || ![_lastRecordedViewStructure isEqualToDictionary:currentViewStructure]) {
[self addViewStructureProperties:currentViewStructure
forKey:DEFAULT_VIEW_KEY
withTimeInterval:timestamp
forKey:TIMESTAMP_KEY];
_lastRecordedViewStructure = currentViewStructure;
}
[super addNewFrameWithTimestamp:timestamp];
}
}
ClueController
to get current view controller and show record indicator view and utils alert- (void)startRecording {
UIViewController *currentViewController = [CLURecordIndicatorViewManager currentViewController];
// If user has previous report file (caused by exception) suggest him to resend it
if ([[CLUReportFileManager sharedManager] isReportZipFileAvailable]) {
[self showAlertWithTitle:@"Send Previous Clue Report"
message:@"Do you want to send your previous Clue Report caused by internal excpetion?"
successActionTitle:@"Send Report"
failureActionTitle:@"Delete Report"
successHandler:^{
[self sendReportWithEmailService];
} failureHandler:^{
[[CLUReportFileManager sharedManager] removeReportZipFile];
}
inViewController:currentViewController];
return;
}
if (!_isRecording) {
_isRecording = YES;
[_reportComposer startRecording];
NSDateComponents *maxTime = [CLURecordIndicatorViewManager defaultMaxTime];
[CLURecordIndicatorViewManager showRecordIndicatorInViewController:currentViewController
withMaxTime:maxTime
target:self
andAction:@selector(stopRecording)];
}
}
ClueController
to get current view controller and show modal mail window- (void)sendReportWithEmailService {
UIViewController *currentViewController = [CLURecordIndicatorViewManager currentViewController];
CLUMailHelper *mailHelper = [[CLUMailHelper alloc] initWithOption:_options];
[mailHelper setMailDelegate:_mailDelegate];
// TODO: test it on real device. Mail isn't working on simulator
if (currentViewController) {
[mailHelper showMailComposeWindowWithViewController:currentViewController];
}
}
+[CLURecordIndicatorViewManager currentViewController]
method should not belong to CLURecordIndicatorViewManager. because it's universal method for getting current view controller across the framework
Any chance we can get support for uploading the .clue file as an issue on github?
There is a #warning in CLUUserInteractionModule
class in startRecording
method
- (void)startRecording {
if (!self.isRecording) {
[super startRecording];
[_gestureRecognizer setObserverDelegate:self];
#warning If some window will be destroyed how to deattach gesture recognizer from it? Possible memory leak!
[[[UIApplication sharedApplication] keyWindow] addGestureRecognizer:_gestureRecognizer];
}
}
We're connecting gesture recognizer to specific window [[UIApplication sharedApplication] keyWindow]
.
A window is considered the key window when it is currently receiving keyboard and non touch-related events. Whereas touch events are delivered to the window in which the touch occurred, events that don’t have an associated coordinate value are delivered to the key window. Only one window at a time can be key
CLUUserInteractionModule
CLUGeneralGestureRecognizer
Right now Clue records in final .clue
file every property and if it's invalid – it just records an empty string.
For example if UIView
doesn't have backgroundColor
property – Clue will record background color as an empty dictionary. It isn't a good idea.
So we need to skip invalid properties at all.
Hi,
I've found a bug:
When I setup the Clue instance and I'm not setted up the UIApplication's window yet, then it occurs a crash.
The problem is in the ClueController.m:236 where you use the app's window bounds size and not the UIScreen.mainScreen...
Improve the readme.md or the above mentioned part of the code.
Thanks
I would like to make use of the PATCH /api/user/ endpoint available for an 'API Key'. But the Fusionauth configuration only allows me to active POST,PUT,DELETE, and GET for a function. I'm using version 1.12. What I had to do is disable all endpoint, thus giving me access to all functions, but this seem like a security risk.
After I shaken the phone to send the report, I find I'm trapped in the mail screen. I'd like to go back to the APP and continue what I was doing. But currently I have to kill the APP to quit the mail view.
I checked the code a little bit, it seems that CLUMailDelegate doesn't dismiss the mailComposeController in mailComposeController(_:didFinishWith:error:)
. I am not sure if it's by design or not. But by adding [controller dismissViewControllerAnimated:YES completion:nil];
after the switch solved my issue. Could you kindly fix this issue on your side? Or I can open a PR with my fix if you need. Thanks!
Result
error type can't be used with Objective-C code. In particular, this applies to the following classes:
CLUObserveModule
CLUDeviceInfoModule
CLUExceptionInfoModule
Where the appendWithJson
method from JSONWriter
needs to be called. As this method is now returning a Result<Int, DataWriterError>
type, it is not visible/available anymore from Objective-C.
So we need to migrate the above three classes to Swift so we can fully take advantage of the Result
return type for writing JSON.
Description
The append
method in the JSONWriter
class created for #9 doesn't provide a straightforward way to handle errors. A nice improvements would be to either:
JSONWriter
to throw a JSONWriterError
as needed.Result<Bool, JSONWriterError>
to encapsulate the semantics of the return value(s).Personally, I prefer using Result
. If we go down this path, we have two possible scenarios:
Result
type (with limited functionality):enum Result<T, ErrorType> {
case success(T)
case error(ErrorType)
}
All the suggested above enhancements are not compatible with Objective-C code. In order to start working on these improvements, we first need to migrate all writing functionality related classes to Swift.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.